summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArnaud Le Blanc <lbarnaud@php.net>2008-11-26 00:59:41 +0000
committerArnaud Le Blanc <lbarnaud@php.net>2008-11-26 00:59:41 +0000
commit6a6289a90dfeec81abb6100baee9ad7155ffe0b1 (patch)
tree864eaff8c2acec8b19f922f39bb40d6679fbaf4a
parent16dc391f1f66f22fec9e2851af3172a4a8396876 (diff)
downloadphp-git-6a6289a90dfeec81abb6100baee9ad7155ffe0b1.tar.gz
MFH: Fixed bugs #44181 & #44182 (extract() and references)
(robin_fernandes at uk dot ibm dot com)
-rw-r--r--ext/standard/array.c11
-rw-r--r--ext/standard/tests/array/extract_variation10.phpt13
-rw-r--r--ext/standard/tests/array/extract_variation11.phpt13
3 files changed, 29 insertions, 8 deletions
diff --git a/ext/standard/array.c b/ext/standard/array.c
index a8ead6de7d..7c3049e1f4 100644
--- a/ext/standard/array.c
+++ b/ext/standard/array.c
@@ -1359,18 +1359,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), Z_STRVAL(final_name), Z_STRLEN(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_hash_update(EG(active_symbol_table), Z_STRVAL(final_name), Z_STRLEN(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
index 0000000000..d520be775e
--- /dev/null
+++ b/ext/standard/tests/array/extract_variation10.phpt
@@ -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
index 0000000000..7f6e08c982
--- /dev/null
+++ b/ext/standard/tests/array/extract_variation11.phpt
@@ -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"