summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2019-03-25 17:33:17 +0100
committerNikita Popov <nikita.ppv@gmail.com>2019-03-25 17:33:17 +0100
commite97577edde49e1f6e86219091b343f80b3b92e65 (patch)
treeec2691eed0f55f9871d8e45d22952ee2043ea280
parent91d4d175ab1a0288f4e37d64a8ec948958ed9528 (diff)
downloadphp-git-e97577edde49e1f6e86219091b343f80b3b92e65.tar.gz
Fixed bug #77793
By making sure that we always first increment the refcount of the new value before we destroy the old one.
-rw-r--r--NEWS6
-rw-r--r--ext/standard/array.c24
-rw-r--r--ext/standard/tests/array/bug77793.phpt18
3 files changed, 37 insertions, 11 deletions
diff --git a/NEWS b/NEWS
index 749ca91a7a..6a586ae9d1 100644
--- a/NEWS
+++ b/NEWS
@@ -2,7 +2,7 @@ PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
?? ??? ????, PHP 7.3.5
-- interbase:
+- Interbase:
. Fixed bug #72175 (Impossibility of creating multiple connections to
Interbase with php 7.x). (Nikita)
@@ -16,6 +16,10 @@ PHP NEWS
- Reflection:
. Fixed bug #77772 (ReflectionClass::getMethods(null) doesn't work). (Nikita)
+- Standard:
+ . Fixed bug #77793 (Segmentation fault in extract() when overwriting
+ reference with itself). (Nikita)
+
28 Mar 2019, PHP 7.3.4
- Core:
diff --git a/ext/standard/array.c b/ext/standard/array.c
index eb4cd6b417..042f97726a 100644
--- a/ext/standard/array.c
+++ b/ext/standard/array.c
@@ -1791,8 +1791,10 @@ static zend_long php_extract_if_exists(zend_array *arr, zend_array *symbol_table
return -1;
}
ZVAL_DEREF(orig_var);
+ ZVAL_DEREF(entry);
+ Z_TRY_ADDREF_P(entry);
zval_ptr_dtor(orig_var);
- ZVAL_COPY_DEREF(orig_var, entry);
+ ZVAL_COPY_VALUE(orig_var, entry);
count++;
}
} ZEND_HASH_FOREACH_END();
@@ -1874,8 +1876,10 @@ static zend_long php_extract_overwrite(zend_array *arr, zend_array *symbol_table
continue;
}
ZVAL_DEREF(orig_var);
+ ZVAL_DEREF(entry);
+ Z_TRY_ADDREF_P(entry);
zval_ptr_dtor(orig_var);
- ZVAL_COPY_DEREF(orig_var, entry);
+ ZVAL_COPY_VALUE(orig_var, entry);
} else {
ZVAL_DEREF(entry);
Z_TRY_ADDREF_P(entry);
@@ -1971,15 +1975,15 @@ static zend_long php_extract_prefix_if_exists(zend_array *arr, zend_array *symbo
return -1;
} else {
ZVAL_DEREF(entry);
+ Z_TRY_ADDREF_P(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(orig_var, entry);
+ ZVAL_COPY_VALUE(orig_var, entry);
} else {
- Z_TRY_ADDREF_P(entry);
zend_hash_add_new(symbol_table, Z_STR(final_name), entry);
}
count++;
@@ -2097,15 +2101,15 @@ static zend_long php_extract_prefix_same(zend_array *arr, zend_array *symbol_tab
return -1;
} else {
ZVAL_DEREF(entry);
+ Z_TRY_ADDREF_P(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(orig_var, entry);
+ ZVAL_COPY_VALUE(orig_var, entry);
} else {
- Z_TRY_ADDREF_P(entry);
zend_hash_add_new(symbol_table, Z_STR(final_name), entry);
}
count++;
@@ -2202,15 +2206,15 @@ static zend_long php_extract_prefix_all(zend_array *arr, zend_array *symbol_tabl
return -1;
} else {
ZVAL_DEREF(entry);
+ Z_TRY_ADDREF_P(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(orig_var, entry);
+ ZVAL_COPY_VALUE(orig_var, entry);
} else {
- Z_TRY_ADDREF_P(entry);
zend_hash_add_new(symbol_table, Z_STR(final_name), entry);
}
count++;
@@ -2309,15 +2313,15 @@ static zend_long php_extract_prefix_invalid(zend_array *arr, zend_array *symbol_
return -1;
} else {
ZVAL_DEREF(entry);
+ Z_TRY_ADDREF_P(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(orig_var, entry);
+ ZVAL_COPY_VALUE(orig_var, entry);
} else {
- Z_TRY_ADDREF_P(entry);
zend_hash_add_new(symbol_table, Z_STR(final_name), entry);
}
count++;
diff --git a/ext/standard/tests/array/bug77793.phpt b/ext/standard/tests/array/bug77793.phpt
new file mode 100644
index 0000000000..6c0ba80a50
--- /dev/null
+++ b/ext/standard/tests/array/bug77793.phpt
@@ -0,0 +1,18 @@
+--TEST--
+Bug #77793: Segmentation fault in extract() when overwriting reference with itself
+--FILE--
+<?php
+
+$str = 'foo';
+$vars = ['var' => $str . 'bar'];
+$var = &$vars['var'];
+extract($vars);
+var_dump($vars, $var);
+
+?>
+--EXPECT--
+array(1) {
+ ["var"]=>
+ &string(6) "foobar"
+}
+string(6) "foobar"