]> granicus.if.org Git - php/commitdiff
MFH: Fixed bugs #44181 & #44182 (extract() and references)
authorArnaud Le Blanc <lbarnaud@php.net>
Wed, 26 Nov 2008 01:00:36 +0000 (01:00 +0000)
committerArnaud Le Blanc <lbarnaud@php.net>
Wed, 26 Nov 2008 01:00:36 +0000 (01:00 +0000)
(robin_fernandes at uk dot ibm dot com)

NEWS
ext/standard/array.c
ext/standard/tests/array/extract_variation10.phpt [new file with mode: 0644]
ext/standard/tests/array/extract_variation11.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 5cad7d0b2e79e5143f2bbb21d66a327abe4ff384..badcb487b0dd9a89911c337d4cb452de05aedd25 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,10 @@ PHP                                                                        NEWS
   inconsistent results). (Arnaud)
 - Fixed bug #46626 (mb_convert_case does not handle apostrophe correctly).
   (Ilia)
+- Fixed bug #44182 (extract($a, EXTR_REFS) can fail to split copy-on-write
+  references). (robin_fernandes at uk dot ibm dot com)
+- Fixed bug #44181 (extract($a, EXTR_OVERWRITE|EXTR_REFS) can fail to create 
+  references to $a). (robin_fernandes at uk dot ibm dot com)
 
 20 Nov 2008, PHP 5.2.7RC4
 - Added logging option for error_log to send directly to SAPI. (Stas)
index f6b9144a8706dbf5ffab80731afea2e779f7000a..64189ff33afd0806d304bb3892f02c059c77dbae 100644 (file)
@@ -1466,20 +1466,13 @@ PHP_FUNCTION(extract)
                                if (extract_refs) {
                                        zval **orig_var;
 
+                                       SEPARATE_ZVAL_TO_MAKE_IS_REF(entry);
+                                       zval_add_ref(entry);
+
                                        if (zend_hash_find(EG(active_symbol_table), final_name.c, final_name.len+1, (void **) &orig_var) == SUCCESS) {
-                                               SEPARATE_ZVAL_TO_MAKE_IS_REF(entry);
-                                               zval_add_ref(entry);
-                                               
                                                zval_ptr_dtor(orig_var);
-
                                                *orig_var = *entry;
                                        } else {
-                                               if ((*var_array)->refcount > 1 || *entry == EG(uninitialized_zval_ptr)) {
-                                                       SEPARATE_ZVAL_TO_MAKE_IS_REF(entry);
-                                               } else {
-                                                       (*entry)->is_ref = 1;
-                                               }
-                                               zval_add_ref(entry);
                                                zend_hash_update(EG(active_symbol_table), final_name.c, final_name.len+1, (void **) entry, sizeof(zval *), NULL);
                                        }
                                } else {
diff --git a/ext/standard/tests/array/extract_variation10.phpt b/ext/standard/tests/array/extract_variation10.phpt
new file mode 100644 (file)
index 0000000..d520be7
--- /dev/null
@@ -0,0 +1,13 @@
+--TEST--
+Test extract() function - ensure EXTR_REFS doesn't mess with isRef flag on COW references to array elements.  
+--FILE--
+<?php
+$a = array('foo' => 'original.foo');
+$nonref = $a['foo'];
+$ref = &$a;
+extract($a, EXTR_REFS);
+$a['foo'] = 'changed.foo';
+var_dump($nonref);
+?>
+--EXPECTF--
+%unicode|string%(12) "original.foo"
diff --git a/ext/standard/tests/array/extract_variation11.phpt b/ext/standard/tests/array/extract_variation11.phpt
new file mode 100644 (file)
index 0000000..7f6e08c
--- /dev/null
@@ -0,0 +1,13 @@
+--TEST--
+Test extract() function - ensure EXTR_REFS works when array is referenced and keys clash with variables in current scope. 
+--FILE--
+<?php
+$a = array('foo' => 'original.foo');
+$ref = &$a;
+$foo = 'test';
+extract($a, EXTR_OVERWRITE|EXTR_REFS);
+$foo = 'changed.foo';
+var_dump($a['foo']);
+?>
+--EXPECTF--
+%unicode|string%(11) "changed.foo"