Skip to content

Commit 78364ef

Browse files
committed
Merge branch 'PHP-8.3'
2 parents f6efd12 + 88537c5 commit 78364ef

File tree

6 files changed

+156
-2
lines changed

6 files changed

+156
-2
lines changed

Zend/zend_vm_def.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -8955,6 +8955,8 @@ ZEND_VM_HANDLER(183, ZEND_BIND_STATIC, CV, ANY, REF)
89558955

89568956
variable_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W);
89578957

8958+
SAVE_OPLINE();
8959+
89588960
ht = ZEND_MAP_PTR_GET(EX(func)->op_array.static_variables_ptr);
89598961
if (!ht) {
89608962
ht = zend_array_dup(EX(func)->op_array.static_variables);
@@ -8964,7 +8966,6 @@ ZEND_VM_HANDLER(183, ZEND_BIND_STATIC, CV, ANY, REF)
89648966

89658967
value = (zval*)((char*)ht->arData + (opline->extended_value & ~(ZEND_BIND_REF|ZEND_BIND_IMPLICIT|ZEND_BIND_EXPLICIT)));
89668968

8967-
SAVE_OPLINE();
89688969
if (opline->extended_value & ZEND_BIND_REF) {
89698970
i_zval_ptr_dtor(variable_ptr);
89708971
if (UNEXPECTED(!Z_ISREF_P(value))) {
@@ -9468,6 +9469,7 @@ ZEND_VM_HANDLER(172, ZEND_FUNC_GET_ARGS, UNUSED|CONST, UNUSED)
94689469
}
94699470

94709471
if (result_size) {
9472+
SAVE_OPLINE();
94719473
uint32_t first_extra_arg = EX(func)->op_array.num_args;
94729474

94739475
ht = zend_new_array(result_size);

Zend/zend_vm_execute.h

+4-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ext/zend_test/php_test.h

+3
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ ZEND_BEGIN_MODULE_GLOBALS(zend_test)
5555
int register_passes;
5656
bool print_stderr_mshutdown;
5757
zend_long limit_copy_file_range;
58+
int observe_opline_in_zendmm;
59+
zend_mm_heap* zend_orig_heap;
60+
zend_mm_heap* zend_test_heap;
5861
zend_test_fiber *active_fiber;
5962
zend_long quantity_value;
6063
zend_string *str_test;

ext/zend_test/test.c

+77
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,17 @@
3131
#include "zend_interfaces.h"
3232
#include "zend_weakrefs.h"
3333
#include "Zend/Optimizer/zend_optimizer.h"
34+
#include "Zend/zend_alloc.h"
3435
#include "test_arginfo.h"
3536
#include "zend_call_stack.h"
3637
#include "zend_exceptions.h"
3738

39+
// `php.h` sets `NDEBUG` when not `PHP_DEBUG` which will make `assert()` from
40+
// assert.h a no-op. In order to have `assert()` working on NDEBUG builds, we
41+
// undefine `NDEBUG` and re-include assert.h
42+
#undef NDEBUG
43+
#include "assert.h"
44+
3845
#if defined(HAVE_LIBXML) && !defined(PHP_WIN32)
3946
# include <libxml/globals.h>
4047
# include <libxml/parser.h>
@@ -622,6 +629,68 @@ static ZEND_FUNCTION(zend_test_crash)
622629
php_printf("%s", invalid);
623630
}
624631

632+
static bool has_opline(zend_execute_data *execute_data)
633+
{
634+
return execute_data
635+
&& execute_data->func
636+
&& ZEND_USER_CODE(execute_data->func->type)
637+
&& execute_data->opline
638+
;
639+
}
640+
641+
void * zend_test_custom_malloc(size_t len)
642+
{
643+
if (has_opline(EG(current_execute_data))) {
644+
assert(EG(current_execute_data)->opline->lineno != (uint32_t)-1);
645+
}
646+
return _zend_mm_alloc(ZT_G(zend_orig_heap), len ZEND_FILE_LINE_EMPTY_CC ZEND_FILE_LINE_EMPTY_CC);
647+
}
648+
649+
void zend_test_custom_free(void *ptr)
650+
{
651+
if (has_opline(EG(current_execute_data))) {
652+
assert(EG(current_execute_data)->opline->lineno != (uint32_t)-1);
653+
}
654+
_zend_mm_free(ZT_G(zend_orig_heap), ptr ZEND_FILE_LINE_EMPTY_CC ZEND_FILE_LINE_EMPTY_CC);
655+
}
656+
657+
void * zend_test_custom_realloc(void * ptr, size_t len)
658+
{
659+
if (has_opline(EG(current_execute_data))) {
660+
assert(EG(current_execute_data)->opline->lineno != (uint32_t)-1);
661+
}
662+
return _zend_mm_realloc(ZT_G(zend_orig_heap), ptr, len ZEND_FILE_LINE_EMPTY_CC ZEND_FILE_LINE_EMPTY_CC);
663+
}
664+
665+
static PHP_INI_MH(OnUpdateZendTestObserveOplineInZendMM)
666+
{
667+
if (new_value == NULL) {
668+
return FAILURE;
669+
}
670+
671+
int int_value = zend_ini_parse_bool(new_value);
672+
673+
if (int_value == 1) {
674+
// `zend_mm_heap` is a private struct, so we have not way to find the
675+
// actual size, but 4096 bytes should be enough
676+
ZT_G(zend_test_heap) = malloc(4096);
677+
memset(ZT_G(zend_test_heap), 0, 4096);
678+
zend_mm_set_custom_handlers(
679+
ZT_G(zend_test_heap),
680+
zend_test_custom_malloc,
681+
zend_test_custom_free,
682+
zend_test_custom_realloc
683+
);
684+
ZT_G(zend_orig_heap) = zend_mm_get_heap();
685+
zend_mm_set_heap(ZT_G(zend_test_heap));
686+
} else if (ZT_G(zend_test_heap)) {
687+
free(ZT_G(zend_test_heap));
688+
ZT_G(zend_test_heap) = NULL;
689+
zend_mm_set_heap(ZT_G(zend_orig_heap));
690+
}
691+
return OnUpdateBool(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
692+
}
693+
625694
static ZEND_FUNCTION(zend_test_fill_packed_array)
626695
{
627696
HashTable *parameter;
@@ -903,6 +972,7 @@ PHP_INI_BEGIN()
903972
STD_PHP_INI_ENTRY("zend_test.quantity_value", "0", PHP_INI_ALL, OnUpdateLong, quantity_value, zend_zend_test_globals, zend_test_globals)
904973
STD_PHP_INI_ENTRY("zend_test.str_test", "", PHP_INI_ALL, OnUpdateStr, str_test, zend_zend_test_globals, zend_test_globals)
905974
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)
975+
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)
906976
PHP_INI_END()
907977

908978
void (*old_zend_execute_ex)(zend_execute_data *execute_data);
@@ -1134,6 +1204,13 @@ PHP_RSHUTDOWN_FUNCTION(zend_test)
11341204
zend_weakrefs_hash_del(&ZT_G(global_weakmap), zend_weakref_key_to_object(obj_key));
11351205
} ZEND_HASH_FOREACH_END();
11361206
zend_hash_destroy(&ZT_G(global_weakmap));
1207+
1208+
if (ZT_G(zend_test_heap)) {
1209+
free(ZT_G(zend_test_heap));
1210+
ZT_G(zend_test_heap) = NULL;
1211+
zend_mm_set_heap(ZT_G(zend_orig_heap));
1212+
}
1213+
11371214
return SUCCESS;
11381215
}
11391216

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
--TEST--
2+
possible segfault in `ZEND_BIND_STATIC`
3+
--DESCRIPTION--
4+
https://github.com/php/php-src/pull/12758
5+
--EXTENSIONS--
6+
zend_test
7+
--INI--
8+
zend_test.observe_opline_in_zendmm=1
9+
--FILE--
10+
<?php
11+
12+
function &ref() {
13+
static $a = 5;
14+
return $a;
15+
}
16+
17+
class Foo {
18+
public static int $i;
19+
public static string $s = "x";
20+
}
21+
22+
var_dump(Foo::$i = "1");
23+
var_dump(Foo::$s, Foo::$i);
24+
var_dump(ref());
25+
26+
echo 'Done.';
27+
?>
28+
--EXPECT--
29+
int(1)
30+
string(1) "x"
31+
int(1)
32+
int(5)
33+
Done.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
--TEST--
2+
possible segfault in `ZEND_FUNC_GET_ARGS`
3+
--DESCRIPTION--
4+
--EXTENSIONS--
5+
zend_test
6+
--INI--
7+
zend_test.observe_opline_in_zendmm=1
8+
--FILE--
9+
<?php
10+
11+
function ref() {
12+
return func_get_args();
13+
}
14+
15+
class Foo {
16+
public static int $i;
17+
public static string $s = "x";
18+
}
19+
20+
var_dump(Foo::$i = "1");
21+
var_dump(Foo::$s, Foo::$i);
22+
var_dump(ref('string', 0));
23+
24+
echo 'Done.';
25+
?>
26+
--EXPECT--
27+
int(1)
28+
string(1) "x"
29+
int(1)
30+
array(2) {
31+
[0]=>
32+
string(6) "string"
33+
[1]=>
34+
int(0)
35+
}
36+
Done.

0 commit comments

Comments
 (0)