diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2019-02-28 09:59:07 +0100 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2019-02-28 09:59:07 +0100 |
commit | 5e6846cad7559ed1f4d2fbc13d595aea6bc18057 (patch) | |
tree | 6dffa6b5b36ffe0f8b4db722b1b9f666746a1cf1 /ext | |
parent | 9d5db37cee4ebe5cfddb47b6fbce5329ddaad2a7 (diff) | |
parent | 019fd1d9bad171ad338fd7fe60dd5b2e6236e489 (diff) | |
download | php-git-5e6846cad7559ed1f4d2fbc13d595aea6bc18057.tar.gz |
Merge branch 'PHP-7.3' into PHP-7.4
Diffstat (limited to 'ext')
-rw-r--r-- | ext/standard/array.c | 24 | ||||
-rw-r--r-- | ext/standard/tests/array/bug77669.phpt | 35 |
2 files changed, 46 insertions, 13 deletions
diff --git a/ext/standard/array.c b/ext/standard/array.c index b84e1e3f86..7b6fca0647 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -2493,35 +2493,33 @@ PHP_FUNCTION(extract) break; } } else { + /* The array might be stored in a local variable that will be overwritten */ + zval array_copy; + ZVAL_COPY(&array_copy, var_array_param); switch (extract_type) { case EXTR_IF_EXISTS: - count = php_extract_if_exists(Z_ARRVAL_P(var_array_param), symbol_table); + count = php_extract_if_exists(Z_ARRVAL(array_copy), symbol_table); break; case EXTR_OVERWRITE: - { - zval zv; - /* The array might be stored in a local variable that will be overwritten */ - ZVAL_COPY(&zv, var_array_param); - count = php_extract_overwrite(Z_ARRVAL(zv), symbol_table); - zval_ptr_dtor(&zv); - } + count = php_extract_overwrite(Z_ARRVAL(array_copy), symbol_table); break; case EXTR_PREFIX_IF_EXISTS: - count = php_extract_prefix_if_exists(Z_ARRVAL_P(var_array_param), symbol_table, prefix); + count = php_extract_prefix_if_exists(Z_ARRVAL(array_copy), symbol_table, prefix); break; case EXTR_PREFIX_SAME: - count = php_extract_prefix_same(Z_ARRVAL_P(var_array_param), symbol_table, prefix); + count = php_extract_prefix_same(Z_ARRVAL(array_copy), symbol_table, prefix); break; case EXTR_PREFIX_ALL: - count = php_extract_prefix_all(Z_ARRVAL_P(var_array_param), symbol_table, prefix); + count = php_extract_prefix_all(Z_ARRVAL(array_copy), symbol_table, prefix); break; case EXTR_PREFIX_INVALID: - count = php_extract_prefix_invalid(Z_ARRVAL_P(var_array_param), symbol_table, prefix); + count = php_extract_prefix_invalid(Z_ARRVAL(array_copy), symbol_table, prefix); break; default: - count = php_extract_skip(Z_ARRVAL_P(var_array_param), symbol_table); + count = php_extract_skip(Z_ARRVAL(array_copy), symbol_table); break; } + zval_ptr_dtor(&array_copy); } RETURN_LONG(count); diff --git a/ext/standard/tests/array/bug77669.phpt b/ext/standard/tests/array/bug77669.phpt new file mode 100644 index 0000000000..1e34f453a2 --- /dev/null +++ b/ext/standard/tests/array/bug77669.phpt @@ -0,0 +1,35 @@ +--TEST-- +Bug #77669: Crash in extract() when overwriting extracted array +--FILE-- +<?php + +function test($mode) { + $foo = []; + $foo["foo"] = 42; + $foo["bar"] = 24; + extract($foo, $mode, ""); + $prefix_foo = []; + $prefix_foo["foo"] = 42; + $prefix_foo["bar"] = 24; + extract($prefix_foo, $mode, "prefix"); +} + +test(EXTR_OVERWRITE); +test(EXTR_SKIP); +test(EXTR_IF_EXISTS); +test(EXTR_PREFIX_SAME); +test(EXTR_PREFIX_ALL); +test(EXTR_PREFIX_INVALID); +test(EXTR_PREFIX_IF_EXISTS); +test(EXTR_REFS | EXTR_OVERWRITE); +test(EXTR_REFS | EXTR_SKIP); +test(EXTR_REFS | EXTR_IF_EXISTS); +test(EXTR_REFS | EXTR_PREFIX_SAME); +test(EXTR_REFS | EXTR_PREFIX_ALL); +test(EXTR_REFS | EXTR_PREFIX_INVALID); +test(EXTR_REFS | EXTR_PREFIX_IF_EXISTS); + +?> +===DONE=== +--EXPECT-- +===DONE=== |