mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
Merge branch 'PHP-8.1' into PHP-8.2
This commit is contained in:
commit
50ccea31f2
7 changed files with 158 additions and 2 deletions
2
NEWS
2
NEWS
|
@ -7,6 +7,8 @@ PHP NEWS
|
|||
error handler). (ilutov)
|
||||
. Fixed oss-fuzz #64209 (In-place modification of filename in
|
||||
php_message_handler_for_zend). (ilutov)
|
||||
. Fixed bug GH-12758 / GH-12768 (Invalid opline in OOM handlers within
|
||||
ZEND_FUNC_GET_ARGS and ZEND_BIND_STATIC). (Florian Engelhardt)
|
||||
|
||||
- Date:
|
||||
. Fixed improbably integer overflow while parsing really large (or small)
|
||||
|
|
|
@ -8851,6 +8851,8 @@ ZEND_VM_HANDLER(183, ZEND_BIND_STATIC, CV, UNUSED, REF)
|
|||
|
||||
variable_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W);
|
||||
|
||||
SAVE_OPLINE();
|
||||
|
||||
ht = ZEND_MAP_PTR_GET(EX(func)->op_array.static_variables_ptr);
|
||||
if (!ht) {
|
||||
ht = zend_array_dup(EX(func)->op_array.static_variables);
|
||||
|
@ -8860,7 +8862,6 @@ ZEND_VM_HANDLER(183, ZEND_BIND_STATIC, CV, UNUSED, REF)
|
|||
|
||||
value = (zval*)((char*)ht->arData + (opline->extended_value & ~(ZEND_BIND_REF|ZEND_BIND_IMPLICIT|ZEND_BIND_EXPLICIT)));
|
||||
|
||||
SAVE_OPLINE();
|
||||
if (opline->extended_value & ZEND_BIND_REF) {
|
||||
if (Z_TYPE_P(value) == IS_CONSTANT_AST) {
|
||||
if (UNEXPECTED(zval_update_constant_ex(value, EX(func)->op_array.scope) != SUCCESS)) {
|
||||
|
@ -9314,6 +9315,7 @@ ZEND_VM_HANDLER(172, ZEND_FUNC_GET_ARGS, UNUSED|CONST, UNUSED)
|
|||
}
|
||||
|
||||
if (result_size) {
|
||||
SAVE_OPLINE();
|
||||
uint32_t first_extra_arg = EX(func)->op_array.num_args;
|
||||
|
||||
ht = zend_new_array(result_size);
|
||||
|
|
5
Zend/zend_vm_execute.h
generated
5
Zend/zend_vm_execute.h
generated
|
@ -10805,6 +10805,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FUNC_GET_ARGS_SPEC_CONST_UNUSE
|
|||
}
|
||||
|
||||
if (result_size) {
|
||||
SAVE_OPLINE();
|
||||
uint32_t first_extra_arg = EX(func)->op_array.num_args;
|
||||
|
||||
ht = zend_new_array(result_size);
|
||||
|
@ -36303,6 +36304,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FUNC_GET_ARGS_SPEC_UNUSED_UNUS
|
|||
}
|
||||
|
||||
if (result_size) {
|
||||
SAVE_OPLINE();
|
||||
uint32_t first_extra_arg = EX(func)->op_array.num_args;
|
||||
|
||||
ht = zend_new_array(result_size);
|
||||
|
@ -48703,6 +48705,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BIND_STATIC_SPEC_CV_UNUSED_HAN
|
|||
|
||||
variable_ptr = EX_VAR(opline->op1.var);
|
||||
|
||||
SAVE_OPLINE();
|
||||
|
||||
ht = ZEND_MAP_PTR_GET(EX(func)->op_array.static_variables_ptr);
|
||||
if (!ht) {
|
||||
ht = zend_array_dup(EX(func)->op_array.static_variables);
|
||||
|
@ -48712,7 +48716,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BIND_STATIC_SPEC_CV_UNUSED_HAN
|
|||
|
||||
value = (zval*)((char*)ht->arData + (opline->extended_value & ~(ZEND_BIND_REF|ZEND_BIND_IMPLICIT|ZEND_BIND_EXPLICIT)));
|
||||
|
||||
SAVE_OPLINE();
|
||||
if (opline->extended_value & ZEND_BIND_REF) {
|
||||
if (Z_TYPE_P(value) == IS_CONSTANT_AST) {
|
||||
if (UNEXPECTED(zval_update_constant_ex(value, EX(func)->op_array.scope) != SUCCESS)) {
|
||||
|
|
|
@ -55,6 +55,9 @@ ZEND_BEGIN_MODULE_GLOBALS(zend_test)
|
|||
int register_passes;
|
||||
bool print_stderr_mshutdown;
|
||||
zend_long limit_copy_file_range;
|
||||
int observe_opline_in_zendmm;
|
||||
zend_mm_heap* zend_orig_heap;
|
||||
zend_mm_heap* zend_test_heap;
|
||||
zend_test_fiber *active_fiber;
|
||||
zend_long quantity_value;
|
||||
zend_string *str_test;
|
||||
|
|
|
@ -30,9 +30,16 @@
|
|||
#include "zend_interfaces.h"
|
||||
#include "zend_weakrefs.h"
|
||||
#include "Zend/Optimizer/zend_optimizer.h"
|
||||
#include "Zend/zend_alloc.h"
|
||||
#include "test.h"
|
||||
#include "test_arginfo.h"
|
||||
|
||||
// `php.h` sets `NDEBUG` when not `PHP_DEBUG` which will make `assert()` from
|
||||
// assert.h a no-op. In order to have `assert()` working on NDEBUG builds, we
|
||||
// undefine `NDEBUG` and re-include assert.h
|
||||
#undef NDEBUG
|
||||
#include "assert.h"
|
||||
|
||||
#if defined(HAVE_LIBXML) && !defined(PHP_WIN32)
|
||||
# include <libxml/globals.h>
|
||||
# include <libxml/parser.h>
|
||||
|
@ -501,6 +508,68 @@ static ZEND_FUNCTION(zend_test_crash)
|
|||
php_printf("%s", invalid);
|
||||
}
|
||||
|
||||
static bool has_opline(zend_execute_data *execute_data)
|
||||
{
|
||||
return execute_data
|
||||
&& execute_data->func
|
||||
&& ZEND_USER_CODE(execute_data->func->type)
|
||||
&& execute_data->opline
|
||||
;
|
||||
}
|
||||
|
||||
void * zend_test_custom_malloc(size_t len)
|
||||
{
|
||||
if (has_opline(EG(current_execute_data))) {
|
||||
assert(EG(current_execute_data)->opline->lineno != (uint32_t)-1);
|
||||
}
|
||||
return _zend_mm_alloc(ZT_G(zend_orig_heap), len ZEND_FILE_LINE_EMPTY_CC ZEND_FILE_LINE_EMPTY_CC);
|
||||
}
|
||||
|
||||
void zend_test_custom_free(void *ptr)
|
||||
{
|
||||
if (has_opline(EG(current_execute_data))) {
|
||||
assert(EG(current_execute_data)->opline->lineno != (uint32_t)-1);
|
||||
}
|
||||
_zend_mm_free(ZT_G(zend_orig_heap), ptr ZEND_FILE_LINE_EMPTY_CC ZEND_FILE_LINE_EMPTY_CC);
|
||||
}
|
||||
|
||||
void * zend_test_custom_realloc(void * ptr, size_t len)
|
||||
{
|
||||
if (has_opline(EG(current_execute_data))) {
|
||||
assert(EG(current_execute_data)->opline->lineno != (uint32_t)-1);
|
||||
}
|
||||
return _zend_mm_realloc(ZT_G(zend_orig_heap), ptr, len ZEND_FILE_LINE_EMPTY_CC ZEND_FILE_LINE_EMPTY_CC);
|
||||
}
|
||||
|
||||
static PHP_INI_MH(OnUpdateZendTestObserveOplineInZendMM)
|
||||
{
|
||||
if (new_value == NULL) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
int int_value = zend_ini_parse_bool(new_value);
|
||||
|
||||
if (int_value == 1) {
|
||||
// `zend_mm_heap` is a private struct, so we have not way to find the
|
||||
// actual size, but 4096 bytes should be enough
|
||||
ZT_G(zend_test_heap) = malloc(4096);
|
||||
memset(ZT_G(zend_test_heap), 0, 4096);
|
||||
zend_mm_set_custom_handlers(
|
||||
ZT_G(zend_test_heap),
|
||||
zend_test_custom_malloc,
|
||||
zend_test_custom_free,
|
||||
zend_test_custom_realloc
|
||||
);
|
||||
ZT_G(zend_orig_heap) = zend_mm_get_heap();
|
||||
zend_mm_set_heap(ZT_G(zend_test_heap));
|
||||
} else if (ZT_G(zend_test_heap)) {
|
||||
free(ZT_G(zend_test_heap));
|
||||
ZT_G(zend_test_heap) = NULL;
|
||||
zend_mm_set_heap(ZT_G(zend_orig_heap));
|
||||
}
|
||||
return OnUpdateBool(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
|
||||
}
|
||||
|
||||
static ZEND_FUNCTION(zend_test_is_pcre_bundled)
|
||||
{
|
||||
ZEND_PARSE_PARAMETERS_NONE();
|
||||
|
@ -743,6 +812,7 @@ PHP_INI_BEGIN()
|
|||
STD_PHP_INI_ENTRY("zend_test.quantity_value", "0", PHP_INI_ALL, OnUpdateLong, quantity_value, zend_zend_test_globals, zend_test_globals)
|
||||
STD_PHP_INI_ENTRY("zend_test.str_test", "", PHP_INI_ALL, OnUpdateStr, str_test, zend_zend_test_globals, zend_test_globals)
|
||||
STD_PHP_INI_ENTRY("zend_test.not_empty_str_test", "val", PHP_INI_ALL, OnUpdateStrNotEmpty, not_empty_str_test, zend_zend_test_globals, zend_test_globals)
|
||||
STD_PHP_INI_BOOLEAN("zend_test.observe_opline_in_zendmm", "0", PHP_INI_ALL, OnUpdateZendTestObserveOplineInZendMM, observe_opline_in_zendmm, zend_zend_test_globals, zend_test_globals)
|
||||
PHP_INI_END()
|
||||
|
||||
void (*old_zend_execute_ex)(zend_execute_data *execute_data);
|
||||
|
@ -899,6 +969,13 @@ PHP_RSHUTDOWN_FUNCTION(zend_test)
|
|||
zend_weakrefs_hash_del(&ZT_G(global_weakmap), zend_weakref_key_to_object(obj_key));
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
zend_hash_destroy(&ZT_G(global_weakmap));
|
||||
|
||||
if (ZT_G(zend_test_heap)) {
|
||||
free(ZT_G(zend_test_heap));
|
||||
ZT_G(zend_test_heap) = NULL;
|
||||
zend_mm_set_heap(ZT_G(zend_orig_heap));
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
|
33
ext/zend_test/tests/opline_dangling.phpt
Normal file
33
ext/zend_test/tests/opline_dangling.phpt
Normal file
|
@ -0,0 +1,33 @@
|
|||
--TEST--
|
||||
possible segfault in `ZEND_BIND_STATIC`
|
||||
--DESCRIPTION--
|
||||
https://github.com/php/php-src/pull/12758
|
||||
--EXTENSIONS--
|
||||
zend_test
|
||||
--INI--
|
||||
zend_test.observe_opline_in_zendmm=1
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
function &ref() {
|
||||
static $a = 5;
|
||||
return $a;
|
||||
}
|
||||
|
||||
class Foo {
|
||||
public static int $i;
|
||||
public static string $s = "x";
|
||||
}
|
||||
|
||||
var_dump(Foo::$i = "1");
|
||||
var_dump(Foo::$s, Foo::$i);
|
||||
var_dump(ref());
|
||||
|
||||
echo 'Done.';
|
||||
?>
|
||||
--EXPECT--
|
||||
int(1)
|
||||
string(1) "x"
|
||||
int(1)
|
||||
int(5)
|
||||
Done.
|
36
ext/zend_test/tests/opline_dangling_02.phpt
Normal file
36
ext/zend_test/tests/opline_dangling_02.phpt
Normal file
|
@ -0,0 +1,36 @@
|
|||
--TEST--
|
||||
possible segfault in `ZEND_FUNC_GET_ARGS`
|
||||
--DESCRIPTION--
|
||||
--EXTENSIONS--
|
||||
zend_test
|
||||
--INI--
|
||||
zend_test.observe_opline_in_zendmm=1
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
function ref() {
|
||||
return func_get_args();
|
||||
}
|
||||
|
||||
class Foo {
|
||||
public static int $i;
|
||||
public static string $s = "x";
|
||||
}
|
||||
|
||||
var_dump(Foo::$i = "1");
|
||||
var_dump(Foo::$s, Foo::$i);
|
||||
var_dump(ref('string', 0));
|
||||
|
||||
echo 'Done.';
|
||||
?>
|
||||
--EXPECT--
|
||||
int(1)
|
||||
string(1) "x"
|
||||
int(1)
|
||||
array(2) {
|
||||
[0]=>
|
||||
string(6) "string"
|
||||
[1]=>
|
||||
int(0)
|
||||
}
|
||||
Done.
|
Loading…
Add table
Add a link
Reference in a new issue