mirror of
https://github.com/php/php-src.git
synced 2025-08-15 13:38:49 +02:00
Merge branch 'PHP-8.4'
* PHP-8.4: Fix GH-16594: Assertion failure in DOM -> before Fix GH-16572: Incorrect result with reflection in low-trigger JIT Fix GH-16577: EG(strtod_state).freelist leaks with opcache.preload
This commit is contained in:
commit
91270aafa5
7 changed files with 84 additions and 5 deletions
|
@ -239,8 +239,11 @@ static bool dom_is_pre_insert_valid_without_step_1(php_libxml_ref_obj *document,
|
||||||
ZEND_ASSERT(parentNode != NULL);
|
ZEND_ASSERT(parentNode != NULL);
|
||||||
|
|
||||||
/* 1. If parent is not a Document, DocumentFragment, or Element node, then throw a "HierarchyRequestError" DOMException.
|
/* 1. If parent is not a Document, DocumentFragment, or Element node, then throw a "HierarchyRequestError" DOMException.
|
||||||
* => Impossible */
|
* => This is possible because we can grab children of attributes etc... (see e.g. GH-16594) */
|
||||||
ZEND_ASSERT(!php_dom_pre_insert_is_parent_invalid(parentNode));
|
if (php_dom_pre_insert_is_parent_invalid(parentNode)) {
|
||||||
|
php_dom_throw_error(HIERARCHY_REQUEST_ERR, dom_get_strict_error(document));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (node->doc != documentNode) {
|
if (node->doc != documentNode) {
|
||||||
php_dom_throw_error(WRONG_DOCUMENT_ERR, dom_get_strict_error(document));
|
php_dom_throw_error(WRONG_DOCUMENT_ERR, dom_get_strict_error(document));
|
||||||
|
|
25
ext/dom/tests/gh16594.phpt
Normal file
25
ext/dom/tests/gh16594.phpt
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
--TEST--
|
||||||
|
GH-16594 (Assertion failure in DOM -> before)
|
||||||
|
--EXTENSIONS--
|
||||||
|
dom
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$v1 = new DOMText("wr");
|
||||||
|
$v2 = new DOMDocument();
|
||||||
|
$v6 = new DOMComment("aw");
|
||||||
|
$v7 = new DOMAttr("r", "iL");
|
||||||
|
|
||||||
|
$v9 = $v2->createElement("test");
|
||||||
|
$v9->setAttributeNodeNS($v7);
|
||||||
|
$v7->appendChild($v1);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$v1->before($v6);
|
||||||
|
} catch (DOMException $e) {
|
||||||
|
echo $e->getMessage(), "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
--EXPECT--
|
||||||
|
Hierarchy Request Error
|
|
@ -4464,6 +4464,12 @@ static zend_result accel_preload(const char *config, bool in_child)
|
||||||
/* Release stored values to avoid dangling pointers */
|
/* Release stored values to avoid dangling pointers */
|
||||||
zend_shutdown_executor_values(/* fast_shutdown */ false);
|
zend_shutdown_executor_values(/* fast_shutdown */ false);
|
||||||
|
|
||||||
|
/* On ZTS we execute `executor_globals_ctor` which reset the freelist and p5s pointers, while on NTS we don't.
|
||||||
|
* We have to clean up the memory before the actual request takes place to avoid a memory leak. */
|
||||||
|
#ifdef ZTS
|
||||||
|
zend_shutdown_strtod();
|
||||||
|
#endif
|
||||||
|
|
||||||
/* We don't want to preload constants.
|
/* We don't want to preload constants.
|
||||||
* Check that zend_shutdown_executor_values() also destroys constants. */
|
* Check that zend_shutdown_executor_values() also destroys constants. */
|
||||||
ZEND_ASSERT(zend_hash_num_elements(EG(zend_constants)) == EG(persistent_constants_count));
|
ZEND_ASSERT(zend_hash_num_elements(EG(zend_constants)) == EG(persistent_constants_count));
|
||||||
|
|
|
@ -10084,6 +10084,7 @@ static int zend_jit_do_fcall(zend_jit_ctx *jit, const zend_op *opline, const zen
|
||||||
if ((!func || func->type == ZEND_USER_FUNCTION)
|
if ((!func || func->type == ZEND_USER_FUNCTION)
|
||||||
&& opline->opcode != ZEND_DO_ICALL) {
|
&& opline->opcode != ZEND_DO_ICALL) {
|
||||||
bool recursive_call_through_jmp = 0;
|
bool recursive_call_through_jmp = 0;
|
||||||
|
uint32_t num_args = 0;
|
||||||
|
|
||||||
// JIT: EX(call) = NULL;
|
// JIT: EX(call) = NULL;
|
||||||
ir_STORE(jit_CALL(rx, call), IR_NULL);
|
ir_STORE(jit_CALL(rx, call), IR_NULL);
|
||||||
|
@ -10148,8 +10149,6 @@ static int zend_jit_do_fcall(zend_jit_ctx *jit, const zend_op *opline, const zen
|
||||||
if (call_num_args <= func->op_array.num_args) {
|
if (call_num_args <= func->op_array.num_args) {
|
||||||
if (!trace || (trace->op == ZEND_JIT_TRACE_END
|
if (!trace || (trace->op == ZEND_JIT_TRACE_END
|
||||||
&& trace->stop >= ZEND_JIT_TRACE_STOP_INTERPRETER)) {
|
&& trace->stop >= ZEND_JIT_TRACE_STOP_INTERPRETER)) {
|
||||||
uint32_t num_args;
|
|
||||||
|
|
||||||
if ((func->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0) {
|
if ((func->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0) {
|
||||||
if (trace) {
|
if (trace) {
|
||||||
num_args = 0;
|
num_args = 0;
|
||||||
|
@ -10345,7 +10344,7 @@ static int zend_jit_do_fcall(zend_jit_ctx *jit, const zend_op *opline, const zen
|
||||||
ir_insn *insn;
|
ir_insn *insn;
|
||||||
|
|
||||||
/* attempt to convert direct recursive call into loop */
|
/* attempt to convert direct recursive call into loop */
|
||||||
begin = jit->bb_start_ref[call_num_args];
|
begin = jit->bb_start_ref[num_args];
|
||||||
ZEND_ASSERT(begin != IR_UNUSED);
|
ZEND_ASSERT(begin != IR_UNUSED);
|
||||||
insn = &jit->ctx.ir_base[begin];
|
insn = &jit->ctx.ir_base[begin];
|
||||||
if (insn->op == IR_BEGIN) {
|
if (insn->op == IR_BEGIN) {
|
||||||
|
|
2
ext/opcache/tests/gh16577.inc
Normal file
2
ext/opcache/tests/gh16577.inc
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
<?php
|
||||||
|
var_dump(1.5);
|
20
ext/opcache/tests/gh16577.phpt
Normal file
20
ext/opcache/tests/gh16577.phpt
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
--TEST--
|
||||||
|
GH-16577 (EG(strtod_state).freelist leaks with opcache.preload)
|
||||||
|
--INI--
|
||||||
|
opcache.enable=1
|
||||||
|
opcache.enable_cli=1
|
||||||
|
opcache.optimization_level=-1
|
||||||
|
opcache.preload={PWD}/gh16577.inc
|
||||||
|
--EXTENSIONS--
|
||||||
|
opcache
|
||||||
|
--SKIPIF--
|
||||||
|
<?php
|
||||||
|
if (PHP_OS_FAMILY == 'Windows') die('skip Preloading is not supported on Windows');
|
||||||
|
?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
echo "Done\n";
|
||||||
|
?>
|
||||||
|
--EXPECT--
|
||||||
|
float(1.5)
|
||||||
|
Done
|
24
ext/opcache/tests/jit/gh16572.phpt
Normal file
24
ext/opcache/tests/jit/gh16572.phpt
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
--TEST--
|
||||||
|
GH-16572 (Incorrect result with reflection in low-trigger JIT)
|
||||||
|
--EXTENSIONS--
|
||||||
|
opcache
|
||||||
|
--INI--
|
||||||
|
opcache.jit=1215
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
function dumpType(ReflectionType $rt) {
|
||||||
|
var_dump($rt::class);
|
||||||
|
dumpType(null);
|
||||||
|
}
|
||||||
|
function test1(): int { }
|
||||||
|
dumpType((new ReflectionFunction('test1'))->getReturnType());
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
string(19) "ReflectionNamedType"
|
||||||
|
|
||||||
|
Fatal error: Uncaught TypeError: dumpType(): Argument #1 ($rt) must be of type ReflectionType, null given, called in %s on line %d and defined in %s:%d
|
||||||
|
Stack trace:
|
||||||
|
#0 %s(%d): dumpType(NULL)
|
||||||
|
#1 %s(%d): dumpType(Object(ReflectionNamedType))
|
||||||
|
#2 {main}
|
||||||
|
thrown in %s on line %d
|
Loading…
Add table
Add a link
Reference in a new issue