diff --git a/ext/dom/parentnode/tree.c b/ext/dom/parentnode/tree.c index ef1ad42b68c..51cdd7cff43 100644 --- a/ext/dom/parentnode/tree.c +++ b/ext/dom/parentnode/tree.c @@ -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)); diff --git a/ext/dom/tests/gh16594.phpt b/ext/dom/tests/gh16594.phpt new file mode 100644 index 00000000000..adfde5948ee --- /dev/null +++ b/ext/dom/tests/gh16594.phpt @@ -0,0 +1,25 @@ +--TEST-- +GH-16594 (Assertion failure in DOM -> before) +--EXTENSIONS-- +dom +--FILE-- +createElement("test"); +$v9->setAttributeNodeNS($v7); +$v7->appendChild($v1); + +try { + $v1->before($v6); +} catch (DOMException $e) { + echo $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +Hierarchy Request Error diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index e8f7a39a3af..406c539f44a 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -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)); diff --git a/ext/opcache/jit/zend_jit_ir.c b/ext/opcache/jit/zend_jit_ir.c index b50dfc2bc05..ecee7dc2afe 100644 --- a/ext/opcache/jit/zend_jit_ir.c +++ b/ext/opcache/jit/zend_jit_ir.c @@ -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) { diff --git a/ext/opcache/tests/gh16577.inc b/ext/opcache/tests/gh16577.inc new file mode 100644 index 00000000000..f016d612817 --- /dev/null +++ b/ext/opcache/tests/gh16577.inc @@ -0,0 +1,2 @@ + +--FILE-- + +--EXPECT-- +float(1.5) +Done diff --git a/ext/opcache/tests/jit/gh16572.phpt b/ext/opcache/tests/jit/gh16572.phpt new file mode 100644 index 00000000000..b3a6850561c --- /dev/null +++ b/ext/opcache/tests/jit/gh16572.phpt @@ -0,0 +1,24 @@ +--TEST-- +GH-16572 (Incorrect result with reflection in low-trigger JIT) +--EXTENSIONS-- +opcache +--INI-- +opcache.jit=1215 +--FILE-- +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