com php-src: Fixed bug #69376 (Wrong ref counting).: Zend/tests/bug69376.phpt Zend/tests/bug69376_2. phpt Zend/zend_hash.c
| From: | Dmitry Stogov | Date: | Mon, 06 Apr 2015 23:35:52 +0000 |
| Subject: | com php-src: Fixed bug #69376 (Wrong ref counting).: Zend/tests/bug69376.phpt Zend/tests/bug69376_2. phpt Zend/zend_hash.c | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-86114@lists.php.net to get a copy of this message | ||
Commit: 55cdde3dd6c986e9e80d2f944ddfaab55c32a93a
Author: Dmitry Stogov <dmitry@zend.com> Tue, 7 Apr 2015 02:35:52 +0300
Parents: 5bd71e97136e433190c4e9ba45ec25451140fc84
Branches: master
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=55cdde3dd6c986e9e80d2f944ddfaab55c32a93a
Log:
Fixed bug #69376 (Wrong ref counting).
Bugs:
https://bugs.php.net/69376
Changed paths:
A Zend/tests/bug69376.phpt
A Zend/tests/bug69376_2.phpt
M Zend/zend_hash.c
Diff:
diff --git a/Zend/tests/bug69376.phpt b/Zend/tests/bug69376.phpt
new file mode 100644
index 0000000..5722b43
--- /dev/null
+++ b/Zend/tests/bug69376.phpt
@@ -0,0 +1,27 @@
+--TEST--
+Bug #69376 (Wrong ref counting)
+--FILE--
+<?php
+function &test() {
+ $var = array();
+ $var[] =& $var;
+
+ return $var;
+};
+
+$a = test();
+$b = $a;
+$b[0] = 123;
+
+print_r($a);
+print_r($b);
+?>
+--EXPECT--
+Array
+(
+ [0] => 123
+)
+Array
+(
+ [0] => 123
+)
diff --git a/Zend/tests/bug69376_2.phpt b/Zend/tests/bug69376_2.phpt
new file mode 100644
index 0000000..e761462
--- /dev/null
+++ b/Zend/tests/bug69376_2.phpt
@@ -0,0 +1,23 @@
+--TEST--
+Bug #69376 (Wrong ref counting)
+--FILE--
+<?php
+$array = array();
+$array[] = &$array;
+$a = $array;
+unset($array);
+$b = $a;
+$b[0] = 123;
+
+print_r($a);
+print_r($b);
+?>
+--EXPECT--
+Array
+(
+ [0] => 123
+)
+Array
+(
+ [0] => 123
+)
diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c
index 1fd3ccf..efc20ba 100644
--- a/Zend/zend_hash.c
+++ b/Zend/zend_hash.c
@@ -1541,7 +1541,9 @@ ZEND_API HashTable* ZEND_FASTCALL zend_array_dup(HashTable *source)
q->h = p->h;
q->key = NULL;
if (Z_OPT_REFCOUNTED_P(data)) {
- if (Z_ISREF_P(data) && Z_REFCOUNT_P(data) == 1) {
+ if (Z_ISREF_P(data) && Z_REFCOUNT_P(data) == 1 &&
+ (Z_TYPE_P(Z_REFVAL_P(data)) != IS_ARRAY ||
+ Z_ARRVAL_P(Z_REFVAL_P(data)) != source)) {
ZVAL_COPY(&q->val, Z_REFVAL_P(data));
} else {
ZVAL_COPY(&q->val, data);