diff options
| author | Xinchen Hui <laruence@gmail.com> | 2015-11-13 19:39:59 -0800 |
|---|---|---|
| committer | Xinchen Hui <laruence@gmail.com> | 2015-11-13 19:39:59 -0800 |
| commit | fce44a5a131f4d897ed9472fcf9a05efdbaa4d03 (patch) | |
| tree | dadd1c791cea91354d14589f14edbb5888de7c21 | |
| parent | 25de928df77d9906c81becddca42143d19d6eedd (diff) | |
| download | php-git-fce44a5a131f4d897ed9472fcf9a05efdbaa4d03.tar.gz | |
Fixed bug #70910 (extract() breaks variable references)
| -rw-r--r-- | NEWS | 1 | ||||
| -rw-r--r-- | ext/standard/array.c | 13 | ||||
| -rw-r--r-- | ext/standard/tests/array/bug70910.phpt | 13 |
3 files changed, 25 insertions, 2 deletions
@@ -5,6 +5,7 @@ PHP NEWS - Core: . Fixed bug #70912 (Null ptr dereference instantiating class with invalid array property). (Laruence) + . Fixed bug #70910 (extract() breaks variable references). (Laruence) . Fixed bug #70898, #70895 (null ptr deref and segfault with crafted callable). (Anatol, Laruence) diff --git a/ext/standard/array.c b/ext/standard/array.c index a327da84b0..c1a716dbdd 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -1895,8 +1895,8 @@ PHP_FUNCTION(extract) } if (Z_TYPE(final_name) == IS_STRING && php_valid_var_name(Z_STRVAL(final_name), Z_STRLEN(final_name))) { + zval *orig_var; if (extract_refs) { - zval *orig_var; ZVAL_MAKE_REF(entry); Z_ADDREF_P(entry); @@ -1913,7 +1913,16 @@ PHP_FUNCTION(extract) } else { ZVAL_DEREF(entry); if (Z_REFCOUNTED_P(entry)) Z_ADDREF_P(entry); - zend_hash_update_ind(symbol_table, Z_STR(final_name), entry); + if ((orig_var = zend_hash_find(symbol_table, Z_STR(final_name))) != NULL) { + if (Z_TYPE_P(orig_var) == IS_INDIRECT) { + orig_var = Z_INDIRECT_P(orig_var); + } + ZVAL_DEREF(orig_var); + zval_ptr_dtor(orig_var); + ZVAL_COPY_VALUE(orig_var, entry); + } else { + zend_hash_update(symbol_table, Z_STR(final_name), entry); + } } count++; } diff --git a/ext/standard/tests/array/bug70910.phpt b/ext/standard/tests/array/bug70910.phpt new file mode 100644 index 0000000000..c7eb36c490 --- /dev/null +++ b/ext/standard/tests/array/bug70910.phpt @@ -0,0 +1,13 @@ +--TEST-- +Bug #70910 (extract() breaks variable references) +--FILE-- +<?php +$var = 'original value'; +$ref =& $var; + +$hash = ['var' => 'new value']; + +extract($hash); +var_dump($var === $ref); +--EXPECT-- +bool(true) |
