Commit 2cc3aa8af7b for php
commit 2cc3aa8af7b31bd346e5cf2f6b760c5848d70d3b
Merge: 8b9691526a0 d5a94412e36
Author: ndossche <7771979+ndossche@users.noreply.github.com>
Date: Sat Oct 10 11:19:34 2026 +0200
Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
Fix throwing behaviour with recursive arrays in VM
diff --cc NEWS
index 54b04dc734b,942a8e9b065..34f540d39b4
--- a/NEWS
+++ b/NEWS
@@@ -13,11 -13,14 +13,12 @@@ PH
. Fixed memory manager keeping a block reallocated to exactly the size of
the next smaller bin in its larger bin, which efree_size() then freed
into the wrong one. (Marc Bennewitz)
+ . Fixed bug GH-24081 (User opcode handlers resume execution against a stale
+ frame under ZEND_VM_KIND_TAILCALL). (devnexen)
. Fixed bug GH-24218 (Invalid opcode for count() of a literal array
without SCCP). (lazerg)
+ . Fix throwing behaviour with recursive arrays in VM. (ndossche)
-- DOM:
- . Fixed bug GH-23352 (UAF reading an attribute value node retained across
- DOMDocument::adoptNode()). (David Carlier)
-
- FPM:
. Fixed bug GH-24229 (fcgi_close() passes shutdown() a literal 1, which is
SHUT_RD in WASI). (Ryosuke Ishibashi)
diff --cc Zend/zend_vm_def.h
index f107f722526,a5605f9a43c..21074bc688d
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@@ -10109,33 -10022,7 +10109,33 @@@ ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_IS_N
ZEND_VM_SMART_BRANCH(result, 0);
}
+ZEND_VM_TYPE_SPEC_HANDLER(ZEND_IS_IDENTICAL, op->op2_type == IS_CONST && (Z_TYPE_P(RT_CONSTANT(op, op->op2)) == IS_ARRAY && zend_hash_num_elements(Z_ARR_P(RT_CONSTANT(op, op->op2))) == 0), ZEND_IS_IDENTICAL_EMPTY_ARRAY, TMPVARCV, CONST, SPEC(SMART_BRANCH,NO_CONST_CONST,COMMUTATIVE))
+{
+ USE_OPLINE
+ zval *op1;
+ bool result;
+
+ op1 = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R);
+ result = Z_TYPE_P(op1) == IS_ARRAY && zend_hash_num_elements(Z_ARR_P(op1)) == 0;
+ FREE_OP1();
+ FREE_OP2();
+ ZEND_VM_SMART_BRANCH(result, 0);
+}
+
+ZEND_VM_TYPE_SPEC_HANDLER(ZEND_IS_NOT_IDENTICAL, op->op2_type == IS_CONST && (Z_TYPE_P(RT_CONSTANT(op, op->op2)) == IS_ARRAY && zend_hash_num_elements(Z_ARR_P(RT_CONSTANT(op, op->op2))) == 0), ZEND_IS_NOT_IDENTICAL_EMPTY_ARRAY, TMPVARCV, CONST, SPEC(SMART_BRANCH,NO_CONST_CONST,COMMUTATIVE))
+{
+ USE_OPLINE
+ zval *op1;
+ bool result;
+
+ op1 = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R);
+ result = Z_TYPE_P(op1) != IS_ARRAY || zend_hash_num_elements(Z_ARR_P(op1)) > 0;
+ FREE_OP1();
+ FREE_OP2();
+ ZEND_VM_SMART_BRANCH(result, 0);
+}
+
- ZEND_VM_TYPE_SPEC_HANDLER(ZEND_IS_IDENTICAL, op->op1_type == IS_CV && (op->op2_type & (IS_CONST|IS_CV)) && !(op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) && !(op2_info & (MAY_BE_UNDEF|MAY_BE_REF)), ZEND_IS_IDENTICAL_NOTHROW, CV, CONST|CV, SPEC(COMMUTATIVE))
+ ZEND_VM_TYPE_SPEC_HANDLER(ZEND_IS_IDENTICAL, op->op1_type == IS_CV && (op->op2_type & (IS_CONST|IS_CV)) && !(op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) && !(op2_info & (MAY_BE_UNDEF|MAY_BE_REF)) && !((op1_info & op2_info) & MAY_BE_ARRAY_OF_ARRAY), ZEND_IS_IDENTICAL_NOTHROW, CV, CONST|CV, SPEC(COMMUTATIVE))
{
/* This is declared below the specializations for MAY_BE_LONG/MAY_BE_DOUBLE so those will be used instead if possible. */
/* This optimizes $x === SOME_CONST_EXPR and $x === $y for non-refs and non-undef, which can't throw. */
diff --cc Zend/zend_vm_execute.h
index f0b244f53c3,f17f7bc3b31..2b5d042666c
Binary files differ