Skip to content

Commit fce44a5

Browse files
committed
Fixed bug #70910 (extract() breaks variable references)
1 parent 25de928 commit fce44a5

File tree

3 files changed

+25
-2
lines changed

3 files changed

+25
-2
lines changed

NEWS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ PHP NEWS
55
- Core:
66
. Fixed bug #70912 (Null ptr dereference instantiating class with invalid
77
array property). (Laruence)
8+
. Fixed bug #70910 (extract() breaks variable references). (Laruence)
89
. Fixed bug #70898, #70895 (null ptr deref and segfault with crafted callable).
910
(Anatol, Laruence)
1011

ext/standard/array.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1895,8 +1895,8 @@ PHP_FUNCTION(extract)
18951895
}
18961896

18971897
if (Z_TYPE(final_name) == IS_STRING && php_valid_var_name(Z_STRVAL(final_name), Z_STRLEN(final_name))) {
1898+
zval *orig_var;
18981899
if (extract_refs) {
1899-
zval *orig_var;
19001900

19011901
ZVAL_MAKE_REF(entry);
19021902
Z_ADDREF_P(entry);
@@ -1913,7 +1913,16 @@ PHP_FUNCTION(extract)
19131913
} else {
19141914
ZVAL_DEREF(entry);
19151915
if (Z_REFCOUNTED_P(entry)) Z_ADDREF_P(entry);
1916-
zend_hash_update_ind(symbol_table, Z_STR(final_name), entry);
1916+
if ((orig_var = zend_hash_find(symbol_table, Z_STR(final_name))) != NULL) {
1917+
if (Z_TYPE_P(orig_var) == IS_INDIRECT) {
1918+
orig_var = Z_INDIRECT_P(orig_var);
1919+
}
1920+
ZVAL_DEREF(orig_var);
1921+
zval_ptr_dtor(orig_var);
1922+
ZVAL_COPY_VALUE(orig_var, entry);
1923+
} else {
1924+
zend_hash_update(symbol_table, Z_STR(final_name), entry);
1925+
}
19171926
}
19181927
count++;
19191928
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
--TEST--
2+
Bug #70910 (extract() breaks variable references)
3+
--FILE--
4+
<?php
5+
$var = 'original value';
6+
$ref =& $var;
7+
8+
$hash = ['var' => 'new value'];
9+
10+
extract($hash);
11+
var_dump($var === $ref);
12+
--EXPECT--
13+
bool(true)

0 commit comments

Comments
 (0)