This commit is contained in:
Nikita Popov 2019-02-28 09:58:01 +01:00
parent af37d58cf7
commit 9ad9cc71ff
3 changed files with 48 additions and 13 deletions

2
NEWS
View file

@ -10,6 +10,8 @@ PHP NEWS
- Standard: - Standard:
. Fixed bug #77664 (Segmentation fault when using undefined constant in . Fixed bug #77664 (Segmentation fault when using undefined constant in
custom wrapper). (Laruence) custom wrapper). (Laruence)
. Fixed bug #77669 (Crash in extract() when overwriting extracted array).
(Nikita)
- MySQLi: - MySQLi:
. Fixed bug #77597 (mysqli_fetch_field hangs scripts). (Nikita) . Fixed bug #77597 (mysqli_fetch_field hangs scripts). (Nikita)

View file

@ -2528,35 +2528,33 @@ PHP_FUNCTION(extract)
break; break;
} }
} else { } 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) { switch (extract_type) {
case EXTR_IF_EXISTS: 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; break;
case EXTR_OVERWRITE: case EXTR_OVERWRITE:
{ count = php_extract_overwrite(Z_ARRVAL(array_copy), symbol_table);
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);
}
break; break;
case EXTR_PREFIX_IF_EXISTS: 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; break;
case EXTR_PREFIX_SAME: 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; break;
case EXTR_PREFIX_ALL: 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; break;
case EXTR_PREFIX_INVALID: 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; break;
default: default:
count = php_extract_skip(Z_ARRVAL_P(var_array_param), symbol_table); count = php_extract_skip(Z_ARRVAL(array_copy), symbol_table);
break; break;
} }
zval_ptr_dtor(&array_copy);
} }
RETURN_LONG(count); RETURN_LONG(count);

View file

@ -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===