From 570f9f628193b5c3c83fde1b5b6a17666259cd30 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 28 Sep 2018 22:27:14 +0200 Subject: Only store zend_type inside reflection type_reference We don't need the full arg_info and the baggage associated with it. Storing the type should be safe, as it's part of structures which are never released during a request (arg_info and in the future prop_info). --- ext/reflection/php_reflection.c | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) (limited to 'ext/reflection/php_reflection.c') diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index c82e29702a..04bc7f82da 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -119,8 +119,7 @@ typedef struct _parameter_reference { /* Struct for type hints */ typedef struct _type_reference { - struct _zend_arg_info *arg_info; - zend_function *fptr; + zend_type type; } type_reference; typedef enum { @@ -202,7 +201,6 @@ static void reflection_free_objects_storage(zend_object *object) /* {{{ */ reflection_object *intern = reflection_object_from_obj(object); parameter_reference *reference; property_reference *prop_reference; - type_reference *typ_reference; if (intern->ptr) { switch (intern->ref_type) { @@ -212,8 +210,6 @@ static void reflection_free_objects_storage(zend_object *object) /* {{{ */ efree(intern->ptr); break; case REF_TYPE_TYPE: - typ_reference = (type_reference*)intern->ptr; - _free_function(typ_reference->fptr); efree(intern->ptr); break; case REF_TYPE_FUNCTION: @@ -1159,7 +1155,7 @@ static void reflection_parameter_factory(zend_function *fptr, zval *closure_obje /* }}} */ /* {{{ reflection_type_factory */ -static void reflection_type_factory(zend_function *fptr, zval *closure_object, struct _zend_arg_info *arg_info, zval *object) +static void reflection_type_factory(zend_type type, zval *object) { reflection_object *intern; type_reference *reference; @@ -1167,15 +1163,9 @@ static void reflection_type_factory(zend_function *fptr, zval *closure_object, s reflection_instantiate(reflection_named_type_ptr, object); intern = Z_REFLECTION_P(object); reference = (type_reference*) emalloc(sizeof(type_reference)); - reference->arg_info = arg_info; - reference->fptr = fptr; + reference->type = type; intern->ptr = reference; intern->ref_type = REF_TYPE_TYPE; - intern->ce = fptr->common.scope; - if (closure_object) { - Z_ADDREF_P(closure_object); - ZVAL_COPY_VALUE(&intern->obj, closure_object); - } } /* }}} */ @@ -2600,7 +2590,7 @@ ZEND_METHOD(reflection_parameter, getType) if (!ZEND_TYPE_IS_SET(param->arg_info->type)) { RETURN_NULL(); } - reflection_type_factory(_copy_function(param->fptr), Z_ISUNDEF(intern->obj)? NULL : &intern->obj, param->arg_info, return_value); + reflection_type_factory(param->arg_info->type, return_value); } /* }}} */ @@ -2858,7 +2848,7 @@ ZEND_METHOD(reflection_type, allowsNull) } GET_REFLECTION_OBJECT_PTR(param); - RETVAL_BOOL(ZEND_TYPE_ALLOW_NULL(param->arg_info->type)); + RETVAL_BOOL(ZEND_TYPE_ALLOW_NULL(param->type)); } /* }}} */ @@ -2874,16 +2864,16 @@ ZEND_METHOD(reflection_type, isBuiltin) } GET_REFLECTION_OBJECT_PTR(param); - RETVAL_BOOL(ZEND_TYPE_IS_CODE(param->arg_info->type)); + RETVAL_BOOL(ZEND_TYPE_IS_CODE(param->type)); } /* }}} */ /* {{{ reflection_type_name */ static zend_string *reflection_type_name(type_reference *param) { - if (ZEND_TYPE_IS_CLASS(param->arg_info->type)) { - return zend_string_copy(ZEND_TYPE_NAME(param->arg_info->type)); + if (ZEND_TYPE_IS_CLASS(param->type)) { + return zend_string_copy(ZEND_TYPE_NAME(param->type)); } else { - char *name = zend_get_type_by_const(ZEND_TYPE_CODE(param->arg_info->type)); + char *name = zend_get_type_by_const(ZEND_TYPE_CODE(param->type)); return zend_string_init(name, strlen(name), 0); } } @@ -3389,7 +3379,7 @@ ZEND_METHOD(reflection_function, getReturnType) RETURN_NULL(); } - reflection_type_factory(_copy_function(fptr), Z_ISUNDEF(intern->obj)? NULL : &intern->obj, &fptr->common.arg_info[-1], return_value); + reflection_type_factory(fptr->common.arg_info[-1].type, return_value); } /* }}} */ -- cgit v1.2.1 From 36a4f58ab9e566b014e73caa24a6fdbc3e8b8f75 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 28 Sep 2018 23:16:10 +0200 Subject: Remove redundant ce from reflection property_reference The ce is already stored in the main reflection object, no need to store it twice. --- ext/reflection/php_reflection.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'ext/reflection/php_reflection.c') diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 04bc7f82da..af15675a65 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -103,7 +103,6 @@ PHPAPI zend_class_entry *reflection_zend_extension_ptr; /* Struct for properties */ typedef struct _property_reference { - zend_class_entry *ce; zend_property_info prop; zend_string *unmangled_name; zend_bool dynamic; @@ -1245,7 +1244,6 @@ static void reflection_property_factory(zend_class_entry *ce, zend_string *name, reflection_instantiate(reflection_property_ptr, object); intern = Z_REFLECTION_P(object); reference = (property_reference*) emalloc(sizeof(property_reference)); - reference->ce = ce; reference->prop = *prop; reference->unmangled_name = zend_string_copy(name); reference->dynamic = dynamic; @@ -5316,7 +5314,6 @@ ZEND_METHOD(reflection_property, __construct) reference->prop = *property_info; reference->dynamic = 0; } - reference->ce = ce; reference->unmangled_name = zend_string_copy(name); intern->ptr = reference; intern->ref_type = REF_TYPE_PROPERTY; @@ -5449,7 +5446,7 @@ ZEND_METHOD(reflection_property, getValue) } if (ref->prop.flags & ZEND_ACC_STATIC) { - member_p = zend_read_static_property_ex(ref->ce, ref->unmangled_name, 0); + member_p = zend_read_static_property_ex(intern->ce, ref->unmangled_name, 0); if (member_p) { ZVAL_COPY_DEREF(return_value, member_p); } @@ -5465,7 +5462,7 @@ ZEND_METHOD(reflection_property, getValue) /* Returns from this function */ } - member_p = zend_read_property_ex(ref->ce, object, ref->unmangled_name, 0, &rv); + member_p = zend_read_property_ex(intern->ce, object, ref->unmangled_name, 0, &rv); if (member_p != &rv) { ZVAL_COPY_DEREF(return_value, member_p); } else { @@ -5504,13 +5501,13 @@ ZEND_METHOD(reflection_property, setValue) } } - zend_update_static_property_ex(ref->ce, ref->unmangled_name, value); + zend_update_static_property_ex(intern->ce, ref->unmangled_name, value); } else { if (zend_parse_parameters(ZEND_NUM_ARGS(), "oz", &object, &value) == FAILURE) { return; } - zend_update_property_ex(ref->ce, object, ref->unmangled_name, value); + zend_update_property_ex(intern->ce, object, ref->unmangled_name, value); } } /* }}} */ @@ -5529,7 +5526,7 @@ ZEND_METHOD(reflection_property, getDeclaringClass) } GET_REFLECTION_OBJECT_PTR(ref); - ce = tmp_ce = ref->ce; + ce = tmp_ce = intern->ce; while (tmp_ce && (tmp_info = zend_hash_find_ptr(&tmp_ce->properties_info, ref->unmangled_name)) != NULL) { if (tmp_info->flags & ZEND_ACC_PRIVATE) { /* it's a private property, so it can't be inherited */ -- cgit v1.2.1 From 96da1fe8a906da8d2927f57ff94ed25a8e6ea411 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sat, 29 Sep 2018 14:47:57 +0200 Subject: Fixed bug #76737 Explicitly prohibit serialization and unserialization of reflection objects. --- ext/reflection/php_reflection.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) (limited to 'ext/reflection/php_reflection.c') diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index af15675a65..14cde3de05 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -6598,6 +6598,12 @@ static void _reflection_write_property(zval *object, zval *member, zval *value, } /* }}} */ +static void reflection_init_class_handlers(zend_class_entry *ce) { + ce->create_object = reflection_objects_new; + ce->serialize = zend_class_serialize_deny; + ce->unserialize = zend_class_unserialize_deny; +} + PHP_MINIT_FUNCTION(reflection) /* {{{ */ { zend_class_entry _reflection_entry; @@ -6619,38 +6625,38 @@ PHP_MINIT_FUNCTION(reflection) /* {{{ */ reflector_ptr = zend_register_internal_interface(&_reflection_entry); INIT_CLASS_ENTRY(_reflection_entry, "ReflectionFunctionAbstract", reflection_function_abstract_functions); - _reflection_entry.create_object = reflection_objects_new; + reflection_init_class_handlers(&_reflection_entry); reflection_function_abstract_ptr = zend_register_internal_class(&_reflection_entry); zend_class_implements(reflection_function_abstract_ptr, 1, reflector_ptr); zend_declare_property_string(reflection_function_abstract_ptr, "name", sizeof("name")-1, "", ZEND_ACC_ABSTRACT); INIT_CLASS_ENTRY(_reflection_entry, "ReflectionFunction", reflection_function_functions); - _reflection_entry.create_object = reflection_objects_new; + reflection_init_class_handlers(&_reflection_entry); reflection_function_ptr = zend_register_internal_class_ex(&_reflection_entry, reflection_function_abstract_ptr); zend_declare_property_string(reflection_function_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC); REGISTER_REFLECTION_CLASS_CONST_LONG(function, "IS_DEPRECATED", ZEND_ACC_DEPRECATED); INIT_CLASS_ENTRY(_reflection_entry, "ReflectionGenerator", reflection_generator_functions); - _reflection_entry.create_object = reflection_objects_new; + reflection_init_class_handlers(&_reflection_entry); reflection_generator_ptr = zend_register_internal_class(&_reflection_entry); INIT_CLASS_ENTRY(_reflection_entry, "ReflectionParameter", reflection_parameter_functions); - _reflection_entry.create_object = reflection_objects_new; + reflection_init_class_handlers(&_reflection_entry); reflection_parameter_ptr = zend_register_internal_class(&_reflection_entry); zend_class_implements(reflection_parameter_ptr, 1, reflector_ptr); zend_declare_property_string(reflection_parameter_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC); INIT_CLASS_ENTRY(_reflection_entry, "ReflectionType", reflection_type_functions); - _reflection_entry.create_object = reflection_objects_new; + reflection_init_class_handlers(&_reflection_entry); reflection_type_ptr = zend_register_internal_class(&_reflection_entry); INIT_CLASS_ENTRY(_reflection_entry, "ReflectionNamedType", reflection_named_type_functions); - _reflection_entry.create_object = reflection_objects_new; + reflection_init_class_handlers(&_reflection_entry); reflection_named_type_ptr = zend_register_internal_class_ex(&_reflection_entry, reflection_type_ptr); INIT_CLASS_ENTRY(_reflection_entry, "ReflectionMethod", reflection_method_functions); - _reflection_entry.create_object = reflection_objects_new; + reflection_init_class_handlers(&_reflection_entry); reflection_method_ptr = zend_register_internal_class_ex(&_reflection_entry, reflection_function_abstract_ptr); zend_declare_property_string(reflection_method_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC); zend_declare_property_string(reflection_method_ptr, "class", sizeof("class")-1, "", ZEND_ACC_PUBLIC); @@ -6663,7 +6669,7 @@ PHP_MINIT_FUNCTION(reflection) /* {{{ */ REGISTER_REFLECTION_CLASS_CONST_LONG(method, "IS_FINAL", ZEND_ACC_FINAL); INIT_CLASS_ENTRY(_reflection_entry, "ReflectionClass", reflection_class_functions); - _reflection_entry.create_object = reflection_objects_new; + reflection_init_class_handlers(&_reflection_entry); reflection_class_ptr = zend_register_internal_class(&_reflection_entry); zend_class_implements(reflection_class_ptr, 1, reflector_ptr); zend_declare_property_string(reflection_class_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC); @@ -6673,18 +6679,18 @@ PHP_MINIT_FUNCTION(reflection) /* {{{ */ REGISTER_REFLECTION_CLASS_CONST_LONG(class, "IS_FINAL", ZEND_ACC_FINAL); INIT_CLASS_ENTRY(_reflection_entry, "ReflectionObject", reflection_object_functions); - _reflection_entry.create_object = reflection_objects_new; + reflection_init_class_handlers(&_reflection_entry); reflection_object_ptr = zend_register_internal_class_ex(&_reflection_entry, reflection_class_ptr); INIT_CLASS_ENTRY(_reflection_entry, "ReflectionProperty", reflection_property_functions); - _reflection_entry.create_object = reflection_objects_new; + reflection_init_class_handlers(&_reflection_entry); reflection_property_ptr = zend_register_internal_class(&_reflection_entry); zend_class_implements(reflection_property_ptr, 1, reflector_ptr); zend_declare_property_string(reflection_property_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC); zend_declare_property_string(reflection_property_ptr, "class", sizeof("class")-1, "", ZEND_ACC_PUBLIC); INIT_CLASS_ENTRY(_reflection_entry, "ReflectionClassConstant", reflection_class_constant_functions); - _reflection_entry.create_object = reflection_objects_new; + reflection_init_class_handlers(&_reflection_entry); reflection_class_constant_ptr = zend_register_internal_class(&_reflection_entry); zend_class_implements(reflection_class_constant_ptr, 1, reflector_ptr); zend_declare_property_string(reflection_class_constant_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC); @@ -6696,13 +6702,13 @@ PHP_MINIT_FUNCTION(reflection) /* {{{ */ REGISTER_REFLECTION_CLASS_CONST_LONG(property, "IS_PRIVATE", ZEND_ACC_PRIVATE); INIT_CLASS_ENTRY(_reflection_entry, "ReflectionExtension", reflection_extension_functions); - _reflection_entry.create_object = reflection_objects_new; + reflection_init_class_handlers(&_reflection_entry); reflection_extension_ptr = zend_register_internal_class(&_reflection_entry); zend_class_implements(reflection_extension_ptr, 1, reflector_ptr); zend_declare_property_string(reflection_extension_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC); INIT_CLASS_ENTRY(_reflection_entry, "ReflectionZendExtension", reflection_zend_extension_functions); - _reflection_entry.create_object = reflection_objects_new; + reflection_init_class_handlers(&_reflection_entry); reflection_zend_extension_ptr = zend_register_internal_class(&_reflection_entry); zend_class_implements(reflection_zend_extension_ptr, 1, reflector_ptr); zend_declare_property_string(reflection_zend_extension_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC); -- cgit v1.2.1