From c67c166f930b2f815a805a3376e9244794e20c31 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 2 Mar 2016 17:50:55 +0300 Subject: Removed zend_fcall_info.symbol_table --- ext/reflection/php_reflection.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'ext/reflection/php_reflection.c') diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index af1e972f60..68aa136d90 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -1430,7 +1430,6 @@ static void _reflection_export(INTERNAL_FUNCTION_PARAMETERS, zend_class_entry *c fci.size = sizeof(fci); fci.function_table = NULL; ZVAL_UNDEF(&fci.function_name); - fci.symbol_table = NULL; fci.object = Z_OBJ(reflector); fci.retval = &retval; fci.param_count = ctor_argc; @@ -1965,7 +1964,6 @@ ZEND_METHOD(reflection_function, invoke) fci.size = sizeof(fci); fci.function_table = NULL; ZVAL_UNDEF(&fci.function_name); - fci.symbol_table = NULL; fci.object = NULL; fci.retval = &retval; fci.param_count = num_args; @@ -2025,7 +2023,6 @@ ZEND_METHOD(reflection_function, invokeArgs) fci.size = sizeof(fci); fci.function_table = NULL; ZVAL_UNDEF(&fci.function_name); - fci.symbol_table = NULL; fci.object = NULL; fci.retval = &retval; fci.param_count = argc; @@ -3257,7 +3254,6 @@ ZEND_METHOD(reflection_method, invoke) fci.size = sizeof(fci); fci.function_table = NULL; ZVAL_UNDEF(&fci.function_name); - fci.symbol_table = NULL; fci.object = object; fci.retval = &retval; fci.param_count = num_args - 1; @@ -3364,7 +3360,6 @@ ZEND_METHOD(reflection_method, invokeArgs) fci.size = sizeof(fci); fci.function_table = NULL; ZVAL_UNDEF(&fci.function_name); - fci.symbol_table = NULL; fci.object = object ? Z_OBJ_P(object) : NULL; fci.retval = &retval; fci.param_count = argc; @@ -4897,7 +4892,6 @@ ZEND_METHOD(reflection_class, newInstance) fci.size = sizeof(fci); fci.function_table = EG(function_table); ZVAL_UNDEF(&fci.function_name); - fci.symbol_table = NULL; fci.object = Z_OBJ_P(return_value); fci.retval = &retval; fci.param_count = num_args; @@ -5001,7 +4995,6 @@ ZEND_METHOD(reflection_class, newInstanceArgs) fci.size = sizeof(fci); fci.function_table = EG(function_table); ZVAL_UNDEF(&fci.function_name); - fci.symbol_table = NULL; fci.object = Z_OBJ_P(return_value); fci.retval = &retval; fci.param_count = argc; -- cgit v1.2.1 From 7abfaac901684da8bdcbccf43682a5557085c917 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 1 Apr 2016 16:17:49 +0300 Subject: Merge zend_execute_data->called_scope into zend_execute_data->This. "called_scope" made sense only for static method calls, for dynamic calls it was always equal to the class of $this. Now EG(This) may store IS_OBJECT + $this or IS_UNUSED + "called_scope" (of course, "called_scope" may be NULL). Some code might need to be adopted to support this change. Checks (Z_OBJ(EX(This))) might need to be converted into (Z_TYPE(EX(This)) == IS_OBJECT). --- ext/reflection/php_reflection.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'ext/reflection/php_reflection.c') diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 68aa136d90..dd3bd6e94d 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -88,7 +88,7 @@ ZEND_DECLARE_MODULE_GLOBALS(reflection) /* Method macros */ #define METHOD_NOTSTATIC(ce) \ - if (!Z_OBJ(EX(This)) || !instanceof_function(Z_OBJCE(EX(This)), ce)) { \ + if ((Z_TYPE(EX(This)) != IS_OBJECT) || !instanceof_function(Z_OBJCE(EX(This)), ce)) { \ php_error_docref(NULL, E_ERROR, "%s() cannot be called statically", get_active_function_name()); \ return; \ } \ @@ -2316,7 +2316,7 @@ ZEND_METHOD(reflection_generator, getThis) REFLECTION_CHECK_VALID_GENERATOR(ex) - if (Z_OBJ(ex->This)) { + if (Z_TYPE(ex->This) == IS_OBJECT) { ZVAL_COPY(return_value, &ex->This); } else { ZVAL_NULL(return_value); -- cgit v1.2.1 From 64f91774f225e78a79c3623b185ae8b64ef9e30b Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sun, 10 Apr 2016 13:01:54 +0200 Subject: Remove IS_VAR_RET_REF flag Instead decide whether a function returned by reference or by value by checking whether the return value has REFERENCE type. This means that functions returning by reference must always return a reference and functions returning by value must not return a reference. --- ext/reflection/php_reflection.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'ext/reflection/php_reflection.c') diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index dd3bd6e94d..186df87fd7 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -5647,7 +5647,9 @@ ZEND_METHOD(reflection_property, getValue) php_error_docref(NULL, E_ERROR, "Internal error: Could not find the property %s::%s", ZSTR_VAL(intern->ce->name), ZSTR_VAL(ref->prop.name)); /* Bails out */ } - ZVAL_DUP(return_value, &CE_STATIC_MEMBERS(intern->ce)[ref->prop.offset]); + member_p = &CE_STATIC_MEMBERS(intern->ce)[ref->prop.offset]; + ZVAL_DEREF(member_p); + ZVAL_COPY(return_value, member_p); } else { const char *class_name, *prop_name; size_t prop_name_len; @@ -5659,7 +5661,8 @@ ZEND_METHOD(reflection_property, getValue) zend_unmangle_property_name_ex(ref->prop.name, &class_name, &prop_name, &prop_name_len); member_p = zend_read_property(ref->ce, object, prop_name, prop_name_len, 1, &rv); - ZVAL_DUP(return_value, member_p); + ZVAL_DEREF(member_p); + ZVAL_COPY(return_value, member_p); } } /* }}} */ -- cgit v1.2.1 From f0a2e8eb13b3971ec11baa2a6029ed7c4cb0064b Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 27 Apr 2016 13:46:38 +0300 Subject: Removed "zend_fcall_info.function_table". It was assigned in many places, but is never used. --- ext/reflection/php_reflection.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'ext/reflection/php_reflection.c') diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 186df87fd7..fe89db9dee 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -1428,7 +1428,6 @@ static void _reflection_export(INTERNAL_FUNCTION_PARAMETERS, zend_class_entry *c /* Call __construct() */ fci.size = sizeof(fci); - fci.function_table = NULL; ZVAL_UNDEF(&fci.function_name); fci.object = Z_OBJ(reflector); fci.retval = &retval; @@ -1461,7 +1460,6 @@ static void _reflection_export(INTERNAL_FUNCTION_PARAMETERS, zend_class_entry *c ZVAL_COPY_VALUE(¶ms[1], output_ptr); ZVAL_STRINGL(&fci.function_name, "reflection::export", sizeof("reflection::export") - 1); - fci.function_table = &reflection_ptr->function_table; fci.object = NULL; fci.retval = &retval; fci.param_count = 2; @@ -1962,7 +1960,6 @@ ZEND_METHOD(reflection_function, invoke) } fci.size = sizeof(fci); - fci.function_table = NULL; ZVAL_UNDEF(&fci.function_name); fci.object = NULL; fci.retval = &retval; @@ -2021,7 +2018,6 @@ ZEND_METHOD(reflection_function, invokeArgs) } ZEND_HASH_FOREACH_END(); fci.size = sizeof(fci); - fci.function_table = NULL; ZVAL_UNDEF(&fci.function_name); fci.object = NULL; fci.retval = &retval; @@ -3252,7 +3248,6 @@ ZEND_METHOD(reflection_method, invoke) } fci.size = sizeof(fci); - fci.function_table = NULL; ZVAL_UNDEF(&fci.function_name); fci.object = object; fci.retval = &retval; @@ -3358,7 +3353,6 @@ ZEND_METHOD(reflection_method, invokeArgs) } fci.size = sizeof(fci); - fci.function_table = NULL; ZVAL_UNDEF(&fci.function_name); fci.object = object ? Z_OBJ_P(object) : NULL; fci.retval = &retval; @@ -4890,7 +4884,6 @@ ZEND_METHOD(reflection_class, newInstance) } fci.size = sizeof(fci); - fci.function_table = EG(function_table); ZVAL_UNDEF(&fci.function_name); fci.object = Z_OBJ_P(return_value); fci.retval = &retval; @@ -4993,7 +4986,6 @@ ZEND_METHOD(reflection_class, newInstanceArgs) } fci.size = sizeof(fci); - fci.function_table = EG(function_table); ZVAL_UNDEF(&fci.function_name); fci.object = Z_OBJ_P(return_value); fci.retval = &retval; -- cgit v1.2.1 From 6499162ff0d8aa6e862d3e3cdd2288b87636b8a1 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 28 Apr 2016 04:13:34 +0300 Subject: - get rid of EG(scope). zend_get_executed_scope() should be used instead. - ichanged zval_update_constant_ex(). Use IS_TYPE_IMMUTABLE flag on shared constants and AST, instead of "inline_change" parameter. --- ext/reflection/php_reflection.c | 42 +++++++++++++++++------------------------ 1 file changed, 17 insertions(+), 25 deletions(-) (limited to 'ext/reflection/php_reflection.c') diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index fe89db9dee..b4bd65182a 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -456,7 +456,7 @@ static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *in zend_class_constant *c; ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->constants_table, key, c) { - zval_update_constant_ex(&c->value, 1, NULL); + zval_update_constant_ex(&c->value, NULL); _class_const_string(str, ZSTR_VAL(key), c, indent); } ZEND_HASH_FOREACH_END(); } @@ -706,14 +706,10 @@ static void _parameter_string(string *str, zend_function *fptr, struct _zend_arg zend_op *precv = _get_recv_op((zend_op_array*)fptr, offset); if (precv && precv->opcode == ZEND_RECV_INIT && precv->op2_type != IS_UNUSED) { zval zv; - zend_class_entry *old_scope; string_write(str, " = ", sizeof(" = ")-1); ZVAL_DUP(&zv, RT_CONSTANT(&fptr->op_array, precv->op2)); - old_scope = EG(scope); - EG(scope) = fptr->common.scope; - zval_update_constant_ex(&zv, 1, NULL); - EG(scope) = old_scope; + zval_update_constant_ex(&zv, fptr->common.scope); if (Z_TYPE(zv) == IS_TRUE) { string_write(str, "true", sizeof("true")-1); } else if (Z_TYPE(zv) == IS_FALSE) { @@ -1931,7 +1927,7 @@ ZEND_METHOD(reflection_function, getStaticVariables) fptr->op_array.static_variables = zend_array_dup(fptr->op_array.static_variables); } ZEND_HASH_FOREACH_VAL(fptr->op_array.static_variables, val) { - if (UNEXPECTED(zval_update_constant_ex(val, 1, fptr->common.scope) != SUCCESS)) { + if (UNEXPECTED(zval_update_constant_ex(val, fptr->common.scope) != SUCCESS)) { return; } } ZEND_HASH_FOREACH_END(); @@ -1969,7 +1965,7 @@ ZEND_METHOD(reflection_function, invoke) fcc.initialized = 1; fcc.function_handler = fptr; - fcc.calling_scope = EG(scope); + fcc.calling_scope = zend_get_executed_scope(); fcc.called_scope = NULL; fcc.object = NULL; @@ -2027,7 +2023,7 @@ ZEND_METHOD(reflection_function, invokeArgs) fcc.initialized = 1; fcc.function_handler = fptr; - fcc.calling_scope = EG(scope); + fcc.calling_scope = zend_get_executed_scope(); fcc.called_scope = NULL; fcc.object = NULL; @@ -2890,11 +2886,7 @@ ZEND_METHOD(reflection_parameter, getDefaultValue) ZVAL_COPY_VALUE(return_value, RT_CONSTANT(¶m->fptr->op_array, precv->op2)); if (Z_CONSTANT_P(return_value)) { - zend_class_entry *old_scope = EG(scope); - - EG(scope) = param->fptr->common.scope; - zval_update_constant_ex(return_value, 0, NULL); - EG(scope) = old_scope; + zval_update_constant_ex(return_value, param->fptr->common.scope); } else { zval_copy_ctor(return_value); } @@ -3965,7 +3957,7 @@ static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value /* this is necessary to make it able to work with default array * properties, returned to user */ if (Z_CONSTANT(prop_copy)) { - if (UNEXPECTED(zval_update_constant_ex(&prop_copy, 1, NULL) != SUCCESS)) { + if (UNEXPECTED(zval_update_constant_ex(&prop_copy, NULL) != SUCCESS)) { return; } } @@ -4621,7 +4613,7 @@ ZEND_METHOD(reflection_class, getConstants) GET_REFLECTION_OBJECT_PTR(ce); array_init(return_value); ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->constants_table, key, c) { - if (UNEXPECTED(zval_update_constant_ex(&c->value, 1, ce) != SUCCESS)) { + if (UNEXPECTED(zval_update_constant_ex(&c->value, ce) != SUCCESS)) { zend_array_destroy(Z_ARRVAL_P(return_value)); return; } @@ -4669,7 +4661,7 @@ ZEND_METHOD(reflection_class, getConstant) GET_REFLECTION_OBJECT_PTR(ce); ZEND_HASH_FOREACH_PTR(&ce->constants_table, c) { - if (UNEXPECTED(zval_update_constant_ex(&c->value, 1, ce) != SUCCESS)) { + if (UNEXPECTED(zval_update_constant_ex(&c->value, ce) != SUCCESS)) { return; } } ZEND_HASH_FOREACH_END(); @@ -4856,10 +4848,10 @@ ZEND_METHOD(reflection_class, newInstance) return; } - old_scope = EG(scope); - EG(scope) = ce; + old_scope = EG(fake_scope); + EG(fake_scope) = ce; constructor = Z_OBJ_HT_P(return_value)->get_constructor(Z_OBJ_P(return_value)); - EG(scope) = old_scope; + EG(fake_scope) = old_scope; /* Run the constructor if there is one */ if (constructor) { @@ -4893,7 +4885,7 @@ ZEND_METHOD(reflection_class, newInstance) fcc.initialized = 1; fcc.function_handler = constructor; - fcc.calling_scope = EG(scope); + fcc.calling_scope = zend_get_executed_scope();; fcc.called_scope = Z_OBJCE_P(return_value); fcc.object = Z_OBJ_P(return_value); @@ -4959,10 +4951,10 @@ ZEND_METHOD(reflection_class, newInstanceArgs) return; } - old_scope = EG(scope); - EG(scope) = ce; + old_scope = EG(fake_scope); + EG(fake_scope) = ce; constructor = Z_OBJ_HT_P(return_value)->get_constructor(Z_OBJ_P(return_value)); - EG(scope) = old_scope; + EG(fake_scope) = old_scope; /* Run the constructor if there is one */ if (constructor) { @@ -4995,7 +4987,7 @@ ZEND_METHOD(reflection_class, newInstanceArgs) fcc.initialized = 1; fcc.function_handler = constructor; - fcc.calling_scope = EG(scope); + fcc.calling_scope = zend_get_executed_scope(); fcc.called_scope = Z_OBJCE_P(return_value); fcc.object = Z_OBJ_P(return_value); -- cgit v1.2.1 From a1c405e0c50c627cdd9a7695b4c7d644238b6b9b Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 29 Apr 2016 14:04:23 +0200 Subject: Fix usages of zend_update_constant_ex If an in-place update in an external zval is performed, it needs to incref'd beforehand, not afterwards. --- ext/reflection/php_reflection.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'ext/reflection/php_reflection.c') diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index b4bd65182a..d618627178 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -2884,11 +2884,9 @@ ZEND_METHOD(reflection_parameter, getDefaultValue) return; } - ZVAL_COPY_VALUE(return_value, RT_CONSTANT(¶m->fptr->op_array, precv->op2)); + ZVAL_COPY(return_value, RT_CONSTANT(¶m->fptr->op_array, precv->op2)); if (Z_CONSTANT_P(return_value)) { zval_update_constant_ex(return_value, param->fptr->common.scope); - } else { - zval_copy_ctor(return_value); } } /* }}} */ -- cgit v1.2.1 From 5595dd5ffa3453f22c0508052417d3b2853f5015 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 29 Apr 2016 22:00:54 +0200 Subject: Revert code to use DUP instead of COPY In a1c405e0c50c627cdd9a7695b4c7d644238b6b9b next to the actual fix I have also switched some (effective) ZVAL_DUPs to ZVAL_COPYs. I'm reverting this part as those were probably there for a reason (presumably issues with non-atomic refcounting on ZTS). --- ext/reflection/php_reflection.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ext/reflection/php_reflection.c') diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index d618627178..5b8569e9f2 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -2884,7 +2884,7 @@ ZEND_METHOD(reflection_parameter, getDefaultValue) return; } - ZVAL_COPY(return_value, RT_CONSTANT(¶m->fptr->op_array, precv->op2)); + ZVAL_DUP(return_value, RT_CONSTANT(¶m->fptr->op_array, precv->op2)); if (Z_CONSTANT_P(return_value)) { zval_update_constant_ex(return_value, param->fptr->common.scope); } -- cgit v1.2.1 From 4b0f9586db3d74e5c3228311f4fece7f77ccb898 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 2 May 2016 11:42:06 +0200 Subject: Add missing update_constants in ReflectionClassConstant Also fix indentation of __toString(). --- ext/reflection/php_reflection.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'ext/reflection/php_reflection.c') diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 5b8569e9f2..2a7ff61957 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -456,8 +456,8 @@ static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *in zend_class_constant *c; ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->constants_table, key, c) { - zval_update_constant_ex(&c->value, NULL); - _class_const_string(str, ZSTR_VAL(key), c, indent); + zval_update_constant_ex(&c->value, c->ce); + _class_const_string(str, ZSTR_VAL(key), c, ZSTR_VAL(sub_indent.buf)); } ZEND_HASH_FOREACH_END(); } string_printf(str, "%s }\n", indent); @@ -633,11 +633,15 @@ static void _const_string(string *str, char *name, zval *value, char *indent) /* {{{ _class_const_string */ static void _class_const_string(string *str, char *name, zend_class_constant *c, char *indent) { - char *type = zend_zval_type_name(&c->value); char *visibility = zend_visibility_string(Z_ACCESS_FLAGS(c->value)); - zend_string *value_str = zval_get_string(&c->value); + zend_string *value_str; + char *type; - string_printf(str, "%s Constant [ %s %s %s ] { %s }\n", + zval_update_constant_ex(&c->value, c->ce); + value_str = zval_get_string(&c->value); + type = zend_zval_type_name(&c->value); + + string_printf(str, "%sConstant [ %s %s %s ] { %s }\n", indent, visibility, type, name, ZSTR_VAL(value_str)); zend_string_release(value_str); @@ -3821,6 +3825,9 @@ ZEND_METHOD(reflection_class_constant, getValue) GET_REFLECTION_OBJECT_PTR(ref); ZVAL_DUP(return_value, &ref->value); + if (Z_CONSTANT_P(return_value)) { + zval_update_constant_ex(return_value, ref->ce); + } } /* }}} */ -- cgit v1.2.1 From a1ed4ab3caf33b59742897b43462d033864bb490 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 10 May 2016 12:13:10 +0200 Subject: Fixed bug #72174 Also fixes a memory leak if ::getValue() is used with __get(). --- ext/reflection/php_reflection.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'ext/reflection/php_reflection.c') diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 50d0ba0023..4c3f6240f4 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -5383,8 +5383,12 @@ ZEND_METHOD(reflection_property, getValue) } zend_unmangle_property_name_ex(ref->prop.name, &class_name, &prop_name, &prop_name_len); - member_p = zend_read_property(ref->ce, object, prop_name, prop_name_len, 1, &rv); - ZVAL_DUP(return_value, member_p); + member_p = zend_read_property(ref->ce, object, prop_name, prop_name_len, 0, &rv); + if (member_p != &rv) { + ZVAL_COPY(return_value, member_p); + } else { + ZVAL_COPY_VALUE(return_value, member_p); + } } } /* }}} */ -- cgit v1.2.1 From 3684d411721c3b5dc85be74c5317e4d6311ad021 Mon Sep 17 00:00:00 2001 From: Joe Watkins Date: Sat, 14 May 2016 06:28:11 +0100 Subject: fix #72209 (ReflectionProperty::getValue() doesn't fail if object doesn't match type) --- ext/reflection/php_reflection.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'ext/reflection/php_reflection.c') diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 38cfec6aa9..13003cae84 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -5648,6 +5648,11 @@ ZEND_METHOD(reflection_property, getValue) return; } + if (!instanceof_function(Z_OBJCE_P(object), ref->ce)) { + _DO_THROW("Given object is not an instance of the class this property was declared in"); + /* Returns from this function */ + } + zend_unmangle_property_name_ex(ref->prop.name, &class_name, &prop_name, &prop_name_len); member_p = zend_read_property(ref->ce, object, prop_name, prop_name_len, 0, &rv); if (member_p != &rv) { -- cgit v1.2.1