summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXinchen Hui <laruence@gmail.com>2015-11-13 19:39:59 -0800
committerXinchen Hui <laruence@gmail.com>2015-11-13 19:39:59 -0800
commitfce44a5a131f4d897ed9472fcf9a05efdbaa4d03 (patch)
treedadd1c791cea91354d14589f14edbb5888de7c21
parent25de928df77d9906c81becddca42143d19d6eedd (diff)
downloadphp-git-fce44a5a131f4d897ed9472fcf9a05efdbaa4d03.tar.gz
Fixed bug #70910 (extract() breaks variable references)
-rw-r--r--NEWS1
-rw-r--r--ext/standard/array.c13
-rw-r--r--ext/standard/tests/array/bug70910.phpt13
3 files changed, 25 insertions, 2 deletions
diff --git a/NEWS b/NEWS
index fd2e129b14..3bcca21085 100644
--- a/NEWS
+++ b/NEWS
@@ -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)