diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2019-03-25 17:33:17 +0100 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2019-03-25 17:33:17 +0100 |
commit | e97577edde49e1f6e86219091b343f80b3b92e65 (patch) | |
tree | ec2691eed0f55f9871d8e45d22952ee2043ea280 | |
parent | 91d4d175ab1a0288f4e37d64a8ec948958ed9528 (diff) | |
download | php-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-- | NEWS | 6 | ||||
-rw-r--r-- | ext/standard/array.c | 24 | ||||
-rw-r--r-- | ext/standard/tests/array/bug77793.phpt | 18 |
3 files changed, 37 insertions, 11 deletions
@@ -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" |