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

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]

index d194993102ad2d4c38071bef16ab037c501c1aa9..eb18b0e46faeb27cdcb4c7aa667e71861102e7c5 100644 (file)
@@ -1461,18 +1461,13 @@ PHP_FUNCTION(extract)
                        if (extract_refs) {
                                zval **orig_var;
 
+                               SEPARATE_ZVAL_TO_MAKE_IS_REF(entry);
+                               zval_add_ref(entry);
+
                                if (zend_u_hash_find(EG(active_symbol_table), Z_TYPE(final_name), Z_UNIVAL(final_name), Z_UNILEN(final_name) + 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 (Z_REFCOUNT_P(var_array) > 1 || *entry == EG(uninitialized_zval_ptr)) {
-                                               SEPARATE_ZVAL_TO_MAKE_IS_REF(entry);
-                                       } else {
-                                               Z_SET_ISREF_PP(entry);
-                                       }
-                                       zval_add_ref(entry);
                                        zend_u_hash_update(EG(active_symbol_table), Z_TYPE(final_name), Z_UNIVAL(final_name), Z_UNILEN(final_name) + 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"