From 22f994ad4e19809f869fcd53aad633cf1111ece8 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Wed, 26 Nov 2008 01:00:36 +0000 Subject: [PATCH] MFH: Fixed bugs #44181 & #44182 (extract() and references) (robin_fernandes at uk dot ibm dot com) --- NEWS | 4 ++++ ext/standard/array.c | 13 +++---------- ext/standard/tests/array/extract_variation10.phpt | 13 +++++++++++++ ext/standard/tests/array/extract_variation11.phpt | 13 +++++++++++++ 4 files changed, 33 insertions(+), 10 deletions(-) create mode 100644 ext/standard/tests/array/extract_variation10.phpt create mode 100644 ext/standard/tests/array/extract_variation11.phpt diff --git a/NEWS b/NEWS index 5cad7d0b2e..badcb487b0 100644 --- 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) diff --git a/ext/standard/array.c b/ext/standard/array.c index f6b9144a87..64189ff33a 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -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 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-- + '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-- + '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" -- 2.50.1