Skip to content

Commit e198546

Browse files
committed
Add flag to forbid dynamic property creation on internal classes
1 parent aa2e68c commit e198546

File tree

2 files changed

+19
-1
lines changed

2 files changed

+19
-1
lines changed

Zend/zend_compile.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ typedef struct _zend_oparray_context {
238238
/* op_array or class is preloaded | | | */
239239
#define ZEND_ACC_PRELOADED (1 << 10) /* X | X | | */
240240
/* | | | */
241-
/* Class Flags (unused: 13, 14, 15, 24...) | | | */
241+
/* Class Flags (unused: 14, 15, 24...) | | | */
242242
/* =========== | | | */
243243
/* | | | */
244244
/* Special class types | | | */
@@ -260,6 +260,9 @@ typedef struct _zend_oparray_context {
260260
/* Class constants updated | | | */
261261
#define ZEND_ACC_CONSTANTS_UPDATED (1 << 12) /* X | | | */
262262
/* | | | */
263+
/* Objects of this class may not have dynamic properties | | | */
264+
#define ZEND_ACC_NO_DYNAMIC_PROPERTIES (1 << 13) /* X | | | */
265+
/* | | | */
263266
/* User class has methods with static variables | | | */
264267
#define ZEND_HAS_STATIC_IN_METHODS (1 << 16) /* X | | | */
265268
/* | | | */

Zend/zend_object_handlers.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,12 @@ static ZEND_COLD zend_never_inline void zend_bad_property_name(void) /* {{{ */
261261
}
262262
/* }}} */
263263

264+
static ZEND_COLD zend_never_inline void zend_forbidden_dynamic_property(
265+
zend_class_entry *ce, zend_string *member) {
266+
zend_throw_error(NULL, "Cannot create dynamic property %s::$%s",
267+
ZSTR_VAL(ce->name), ZSTR_VAL(member));
268+
}
269+
264270
static zend_always_inline uintptr_t zend_get_property_offset(zend_class_entry *ce, zend_string *member, int silent, void **cache_slot, zend_property_info **info_ptr) /* {{{ */
265271
{
266272
zval *zv;
@@ -772,6 +778,11 @@ ZEND_API zval *zend_std_write_property(zend_object *zobj, zend_string *name, zva
772778

773779
ZVAL_COPY_VALUE(variable_ptr, value);
774780
} else {
781+
if (UNEXPECTED(zobj->ce->ce_flags & ZEND_ACC_NO_DYNAMIC_PROPERTIES)) {
782+
zend_forbidden_dynamic_property(zobj->ce, name);
783+
variable_ptr = &EG(error_zval);
784+
goto exit;
785+
}
775786
if (!zobj->properties) {
776787
rebuild_object_properties(zobj);
777788
}
@@ -935,6 +946,10 @@ ZEND_API zval *zend_std_get_property_ptr_ptr(zend_object *zobj, zend_string *nam
935946
}
936947
if (EXPECTED(!zobj->ce->__get) ||
937948
UNEXPECTED((*zend_get_property_guard(zobj, name)) & IN_GET)) {
949+
if (UNEXPECTED(zobj->ce->ce_flags & ZEND_ACC_NO_DYNAMIC_PROPERTIES)) {
950+
zend_forbidden_dynamic_property(zobj->ce, name);
951+
return NULL;
952+
}
938953
if (UNEXPECTED(!zobj->properties)) {
939954
rebuild_object_properties(zobj);
940955
}

0 commit comments

Comments
 (0)