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);
|
||||
|
||||
/* 1. If parent is not a Document, DocumentFragment, or Element node, then throw a "HierarchyRequestError" DOMException.
|
||||
* => Impossible */
|
||||
ZEND_ASSERT(!php_dom_pre_insert_is_parent_invalid(parentNode));
|
||||
* => This is possible because we can grab children of attributes etc... (see e.g. GH-16594) */
|
||||
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) {
|
||||
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 */
|
||||
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.
|
||||
* Check that zend_shutdown_executor_values() also destroys constants. */
|
||||
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)
|
||||
&& opline->opcode != ZEND_DO_ICALL) {
|
||||
bool recursive_call_through_jmp = 0;
|
||||
uint32_t num_args = 0;
|
||||
|
||||
// JIT: EX(call) = 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 (!trace || (trace->op == ZEND_JIT_TRACE_END
|
||||
&& trace->stop >= ZEND_JIT_TRACE_STOP_INTERPRETER)) {
|
||||
uint32_t num_args;
|
||||
|
||||
if ((func->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0) {
|
||||
if (trace) {
|
||||
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;
|
||||
|
||||
/* 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);
|
||||
insn = &jit->ctx.ir_base[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