Commit 084afea4ca2 for php
commit 084afea4ca23b397692825fa024e401ab46b0b05
Merge: fd9b8e75693 b3a8e07fe56
Author: Weilin Du <weilindu@php.net>
Date: Mon Nov 9 20:21:45 2026 +0800
Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
Fix use-after-free in zend_compile_const_decl() under opcache (#25302)
diff --cc NEWS
index 4ed7877b679,a84629e1877..f47d51bc7d2
--- a/NEWS
+++ b/NEWS
@@@ -12,10 -12,12 +12,12 @@@ PH
of class names in implements, catch, and trait use lists. (Jorg Sowa)
. Fixed AST export dropping the braces of dynamic class constant fetches.
(Jorg Sowa)
+ . Fixed bug GH-25238 (ReflectionProperty::isInitialized() skips lazy init once
+ cached). (lazerg)
. Fixed bug GH-25265 (Misaligned read for virtual internal props in
hooked subclass). (Lazizbek Ergashev)
- . Fixed bug GH-25299 (Exception string code is lost after unserialize()).
- (Lazizbek Ergashev, David Carlier)
+ . Fixed bug GH-25302 (Use-after-free in zend_compile_const_decl() with
+ OPcache during concurrent compilation). (Nicolas Grekas)
- Curl:
. Fixed curl_reset() retaining CURLOPT_PRIVATE after reset. (lacatoire)
diff --cc Zend/zend_compile.c
index 89220cb48aa,d3538a240a7..eeefd212d92
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@@ -9718,33 -9491,8 +9723,31 @@@ static void zend_compile_const_decl(zen
name_node.op_type = IS_CONST;
ZVAL_STR(&name_node.u.constant, name);
- zend_emit_op(NULL, ZEND_DECLARE_CONST, &name_node, &value_node);
+ last_op = zend_emit_op(NULL, ZEND_DECLARE_CONST, &name_node, &value_node);
-
- zend_register_seen_symbol(name, ZEND_SYMBOL_CONST);
+ }
+ if (attributes_ast == NULL) {
+ return;
}
+ /* Validate: attributes can only be applied to one constant at a time
+ * Since we store the AST for the attributes in the list of children,
+ * there should be exactly 2 children. */
+ if (list->children > 2) {
+ zend_error_noreturn(
+ E_COMPILE_ERROR,
+ "Cannot apply attributes to multiple constants at once"
+ );
+ }
+
+ HashTable *attributes = NULL;
+ zend_compile_attributes(&attributes, list->child[1], 0, ZEND_ATTRIBUTE_TARGET_CONST, 0);
+
+ ZEND_ASSERT(last_op != NULL);
+ last_op->opcode = ZEND_DECLARE_ATTRIBUTED_CONST;
+ znode attribs_node;
+ attribs_node.op_type = IS_CONST;
+ ZVAL_PTR(&attribs_node.u.constant, attributes);
+ zend_emit_op_data(&attribs_node);
+ CG(active_op_array)->fn_flags |= ZEND_ACC_PTR_OPS;
}
/* }}}*/