Skip to content

Commit b1821ad

Browse files
committed
Add flag to forbid dynamic property creation on internal classes
1 parent 75bac16 commit b1821ad

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
@@ -229,7 +229,7 @@ typedef struct _zend_oparray_context {
229229
/* op_array or class is preloaded | | | */
230230
#define ZEND_ACC_PRELOADED (1 << 10) /* X | X | | */
231231
/* | | | */
232-
/* Class Flags (unused: 13, 14, 15, 24...) | | | */
232+
/* Class Flags (unused: 14, 15, 24...) | | | */
233233
/* =========== | | | */
234234
/* | | | */
235235
/* Special class types | | | */
@@ -251,6 +251,9 @@ typedef struct _zend_oparray_context {
251251
/* Class constants updated | | | */
252252
#define ZEND_ACC_CONSTANTS_UPDATED (1 << 12) /* X | | | */
253253
/* | | | */
254+
/* Objects of this class may not have dynamic properties | | | */
255+
#define ZEND_ACC_NO_DYNAMIC_PROPERTIES (1 << 13) /* X | | | */
256+
/* | | | */
254257
/* User class has methods with static variables | | | */
255258
#define ZEND_HAS_STATIC_IN_METHODS (1 << 16) /* X | | | */
256259
/* | | | */

Zend/zend_object_handlers.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,12 @@ static ZEND_COLD zend_never_inline void zend_bad_property_name(void) /* {{{ */
374374
}
375375
/* }}} */
376376

377+
static ZEND_COLD zend_never_inline void zend_forbidden_dynamic_property(
378+
zend_class_entry *ce, zend_string *member) {
379+
zend_throw_error(NULL, "Cannot create dynamic property %s::$%s",
380+
ZSTR_VAL(ce->name), ZSTR_VAL(member));
381+
}
382+
377383
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) /* {{{ */
378384
{
379385
zval *zv;
@@ -885,6 +891,11 @@ ZEND_API zval *zend_std_write_property(zend_object *zobj, zend_string *name, zva
885891

886892
ZVAL_COPY_VALUE(variable_ptr, value);
887893
} else {
894+
if (UNEXPECTED(zobj->ce->ce_flags & ZEND_ACC_NO_DYNAMIC_PROPERTIES)) {
895+
zend_forbidden_dynamic_property(zobj->ce, name);
896+
variable_ptr = &EG(error_zval);
897+
goto exit;
898+
}
888899
if (!zobj->properties) {
889900
rebuild_object_properties(zobj);
890901
}
@@ -1048,6 +1059,10 @@ ZEND_API zval *zend_std_get_property_ptr_ptr(zend_object *zobj, zend_string *nam
10481059
}
10491060
if (EXPECTED(!zobj->ce->__get) ||
10501061
UNEXPECTED((*zend_get_property_guard(zobj, name)) & IN_GET)) {
1062+
if (UNEXPECTED(zobj->ce->ce_flags & ZEND_ACC_NO_DYNAMIC_PROPERTIES)) {
1063+
zend_forbidden_dynamic_property(zobj->ce, name);
1064+
return NULL;
1065+
}
10511066
if (UNEXPECTED(!zobj->properties)) {
10521067
rebuild_object_properties(zobj);
10531068
}

0 commit comments

Comments
 (0)