Fix persisting of inherited class constants

Class constants are inherited to user classes without cloning. Thus, internal
class constants should not be persisted at all. Simply keep pointing to the
internal class constant.

Fixes GH-14109
Closes GH-14114
This commit is contained in:
Ilija Tovilo 2024-05-02 21:11:29 +02:00
parent f8d1864bbb
commit 42ede5597e
No known key found for this signature in database
GPG Key ID: A4F5D403F118200A
3 changed files with 16 additions and 1 deletions

4
NEWS
View File

@ -17,6 +17,10 @@ PHP NEWS
. Fix crash when calling childNodes next() when iterator is exhausted.
(nielsdos)
- Opcache:
. Fixed bug GH-14109 (Fix accidental persisting of internal class constant in
shm). (ilutov)
- XML:
. Fixed bug GH-14124 (Segmentation fault with XML extension under certain
memory limit). (nielsdos)

View File

@ -802,12 +802,17 @@ static zend_property_info *zend_persist_property_info(zend_property_info *prop)
static void zend_persist_class_constant(zval *zv)
{
zend_class_constant *c = zend_shared_alloc_get_xlat_entry(Z_PTR_P(zv));
zend_class_constant *orig_c = Z_PTR_P(zv);
zend_class_constant *c = zend_shared_alloc_get_xlat_entry(orig_c);
zend_class_entry *ce;
if (c) {
Z_PTR_P(zv) = c;
return;
} else if (((orig_c->ce->ce_flags & ZEND_ACC_IMMUTABLE) && !(Z_CONSTANT_FLAGS(orig_c->value) & CONST_OWNED))
|| orig_c->ce->type == ZEND_INTERNAL_CLASS) {
/* Class constant comes from a different file in shm or internal class, keep existing pointer. */
return;
} else if (!ZCG(current_persistent_script)->corrupted
&& zend_accel_in_shm(Z_PTR_P(zv))) {
return;

View File

@ -26,6 +26,7 @@
#include "zend_shared_alloc.h"
#include "zend_operators.h"
#include "zend_attributes.h"
#include "zend_constants.h"
#define ADD_DUP_SIZE(m,s) ZCG(current_persistent_script)->size += zend_shared_memdup_size((void*)m, s)
#define ADD_SIZE(m) ZCG(current_persistent_script)->size += ZEND_ALIGNED_SIZE(m)
@ -386,6 +387,11 @@ static void zend_persist_class_constant_calc(zval *zv)
zend_class_constant *c = Z_PTR_P(zv);
if (!zend_shared_alloc_get_xlat_entry(c)) {
if (((c->ce->ce_flags & ZEND_ACC_IMMUTABLE) && !(Z_CONSTANT_FLAGS(c->value) & CONST_OWNED))
|| c->ce->type == ZEND_INTERNAL_CLASS) {
/* Class constant comes from a different file in shm or internal class, keep existing pointer. */
return;
}
if (!ZCG(current_persistent_script)->corrupted
&& zend_accel_in_shm(Z_PTR_P(zv))) {
return;