Skip to content

Commit 8e0e492

Browse files
rejig the code a bit so it validates the object and constructor before setting any values to avoid leaking memory
1 parent 4d03925 commit 8e0e492

File tree

1 file changed

+16
-14
lines changed

1 file changed

+16
-14
lines changed

ext/reflection/php_reflection.c

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5164,33 +5164,35 @@ ZEND_METHOD(ReflectionClass, newInstanceFromData)
51645164
RETURN_THROWS();
51655165
}
51665166

5167-
ZEND_HASH_FOREACH_STR_KEY_VAL(data, key, val) {
5168-
zend_update_property_ex(ce, Z_OBJ_P(return_value), key, val);
5169-
} ZEND_HASH_FOREACH_END();
5170-
51715167
const zend_class_entry *old_scope = EG(fake_scope);
51725168
EG(fake_scope) = ce;
51735169
constructor = Z_OBJ_HT_P(return_value)->get_constructor(Z_OBJ_P(return_value));
51745170
EG(fake_scope) = old_scope;
51755171

5176-
/* Run the constructor if there is one */
5177-
if (constructor) {
5178-
if (!(constructor->common.fn_flags & ZEND_ACC_PUBLIC)) {
5179-
zend_throw_exception_ex(reflection_exception_ptr, 0, "Access to non-public constructor of class %s", ZSTR_VAL(ce->name));
5180-
zval_ptr_dtor(return_value);
5181-
RETURN_THROWS();
5182-
}
5172+
/* Validate the constructor before we set any property values to avoid leaking memory */
5173+
if (!constructor && argc) {
5174+
zend_throw_exception_ex(reflection_exception_ptr, 0, "Class %s does not have a constructor, so you cannot pass any constructor arguments", ZSTR_VAL(ce->name));
5175+
RETURN_THROWS();
5176+
}
5177+
5178+
if (constructor && !(constructor->common.fn_flags & ZEND_ACC_PUBLIC)) {
5179+
zend_throw_exception_ex(reflection_exception_ptr, 0, "Access to non-public constructor of class %s", ZSTR_VAL(ce->name));
5180+
RETURN_THROWS();
5181+
}
5182+
5183+
/* All good - set the property values and call the constructor if there is one */
5184+
ZEND_HASH_FOREACH_STR_KEY_VAL(data, key, val) {
5185+
zend_update_property_ex(ce, Z_OBJ_P(return_value), key, val);
5186+
} ZEND_HASH_FOREACH_END();
51835187

5188+
if (constructor) {
51845189
zend_call_known_function(
51855190
constructor, Z_OBJ_P(return_value), Z_OBJCE_P(return_value), NULL, 0, NULL, args);
51865191

51875192
if (EG(exception)) {
51885193
zend_object_store_ctor_failed(Z_OBJ_P(return_value));
51895194
RETURN_THROWS();
51905195
}
5191-
} else if (argc) {
5192-
zend_throw_exception_ex(reflection_exception_ptr, 0, "Class %s does not have a constructor, so you cannot pass any constructor arguments", ZSTR_VAL(ce->name));
5193-
RETURN_THROWS();
51945196
}
51955197
}
51965198
/* }}} */

0 commit comments

Comments
 (0)