From 715d5d2855a0c6946ac99f1631a4dd9168b0cbfe Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 13 Aug 2015 13:56:29 +0300 Subject: Get rid of implicit type casting in GC_*() macros in Zend/zend_types.h. This prevented compilation warnings and disclosed few incorrect usages in Zend/zend_vm_def.h and ext/dom/xpath.c. Now explicit type casting may be required on call site. This may break some C extension code, but it shoulfn't be a problem to add explicit casting. --- 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 463cbd6a3a..00731c70c3 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -2314,7 +2314,7 @@ ZEND_METHOD(reflection_generator, getExecutingGenerator) REFLECTION_CHECK_VALID_GENERATOR(ex) current = zend_generator_get_current(generator); - ++GC_REFCOUNT(current); + ++GC_REFCOUNT(¤t->std); ZVAL_OBJ(return_value, (zend_object *) current); } -- cgit v1.2.1 From 4744eec753786e18b28887463bdcb3f1e91efb60 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Sat, 3 Oct 2015 20:08:21 -0700 Subject: Fixed bug #70631 (Another Segfault in gc_remove_from_buffer()) --- ext/reflection/php_reflection.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) (limited to 'ext/reflection/php_reflection.c') diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index eff8bdc65b..3bf49eafc7 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -242,6 +242,25 @@ static void _default_lookup_entry(zval *object, char *name, int name_len, zval * /* }}} */ #endif +static void reflection_zval_deep_copy(zval **p) +{ + zval *value; + + ALLOC_ZVAL(value); + *value = **p; + if (Z_TYPE_P(value) == IS_ARRAY) { + HashTable *ht; + + ALLOC_HASHTABLE(ht); + zend_hash_init(ht, zend_hash_num_elements(Z_ARRVAL_P(value)), NULL, ZVAL_PTR_DTOR, 0); + zend_hash_copy(ht, Z_ARRVAL_P(value), (copy_ctor_func_t) reflection_zval_deep_copy, NULL, sizeof(zval *)); + Z_ARRVAL_P(value) = ht; + } else { + zval_copy_ctor(value); + } + INIT_PZVAL(value); + *p = value; +} static void reflection_register_implement(zend_class_entry *class_entry, zend_class_entry *interface_entry TSRMLS_DC) /* {{{ */ { zend_uint num_interfaces = ++class_entry->num_interfaces; @@ -2606,7 +2625,16 @@ ZEND_METHOD(reflection_parameter, getDefaultValue) *return_value = *precv->op2.zv; INIT_PZVAL(return_value); if (!IS_CONSTANT_TYPE(Z_TYPE_P(return_value))) { - zval_copy_ctor(return_value); + if (Z_TYPE_P(return_value) != IS_ARRAY) { + zval_copy_ctor(return_value); + } else { + HashTable *ht; + + ALLOC_HASHTABLE(ht); + zend_hash_init(ht, zend_hash_num_elements(Z_ARRVAL_P(return_value)), NULL, ZVAL_PTR_DTOR, 0); + zend_hash_copy(ht, Z_ARRVAL_P(return_value), (copy_ctor_func_t) reflection_zval_deep_copy, NULL, sizeof(zval *)); + Z_ARRVAL_P(return_value) = ht; + } } old_scope = EG(scope); EG(scope) = param->fptr->common.scope; -- cgit v1.2.1 From 6876112c89e6dc4434e64a78084ca3bb118c98bd Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Sat, 3 Oct 2015 20:14:55 -0700 Subject: Fixed the third one of (segfault in gc_remove_from_buffer()) This one maybe only used in debug mode, so no bug report and no test script provided --- ext/reflection/php_reflection.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) (limited to 'ext/reflection/php_reflection.c') diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 3bf49eafc7..e1a2c57668 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -750,14 +750,18 @@ static void _parameter_string(string *str, zend_function *fptr, struct _zend_arg zend_class_entry *old_scope; string_write(str, " = ", sizeof(" = ")-1); - ALLOC_ZVAL(zv); - *zv = *precv->op2.zv; - zval_copy_ctor(zv); - INIT_PZVAL(zv); - old_scope = EG(scope); - EG(scope) = fptr->common.scope; - zval_update_constant_ex(&zv, 1, NULL TSRMLS_CC); - EG(scope) = old_scope; + if (IS_CONSTANT_TYPE(Z_TYPE_P(precv->op2.zv))) { + ALLOC_ZVAL(zv); + *zv = *precv->op2.zv; + zval_copy_ctor(zv); + INIT_PZVAL(zv); + old_scope = EG(scope); + EG(scope) = fptr->common.scope; + zval_update_constant_ex(&zv, 1, NULL TSRMLS_CC); + EG(scope) = old_scope; + } else { + zv = precv->op2.zv; + } if (Z_TYPE_P(zv) == IS_BOOL) { if (Z_LVAL_P(zv)) { string_write(str, "true", sizeof("true")-1); @@ -782,7 +786,9 @@ static void _parameter_string(string *str, zend_function *fptr, struct _zend_arg zval_dtor(&zv_copy); } } - zval_ptr_dtor(&zv); + if (zv != precv->op2.zv) { + zval_ptr_dtor(&zv); + } } } string_write(str, " ]", sizeof(" ]")-1); -- cgit v1.2.1 From 23b372d358577c8146e4c35e936413e5a43043d9 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 9 Oct 2015 18:41:15 +0200 Subject: Forbid "fake" closure rebinding --- ext/reflection/php_reflection.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'ext/reflection/php_reflection.c') diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 00731c70c3..a095120e18 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -1762,7 +1762,7 @@ ZEND_METHOD(reflection_function, getClosure) } GET_REFLECTION_OBJECT_PTR(fptr); - zend_create_closure(return_value, fptr, NULL, NULL, NULL); + zend_create_fake_closure(return_value, fptr, NULL, NULL, NULL); } /* }}} */ @@ -3144,7 +3144,7 @@ ZEND_METHOD(reflection_method, getClosure) GET_REFLECTION_OBJECT_PTR(mptr); if (mptr->common.fn_flags & ZEND_ACC_STATIC) { - zend_create_closure(return_value, mptr, mptr->common.scope, mptr->common.scope, NULL); + zend_create_fake_closure(return_value, mptr, mptr->common.scope, mptr->common.scope, NULL); } else { if (zend_parse_parameters(ZEND_NUM_ARGS(), "o", &obj) == FAILURE) { return; @@ -3161,7 +3161,7 @@ ZEND_METHOD(reflection_method, getClosure) { ZVAL_COPY(return_value, obj); } else { - zend_create_closure(return_value, mptr, mptr->common.scope, Z_OBJCE_P(obj), obj); + zend_create_fake_closure(return_value, mptr, mptr->common.scope, Z_OBJCE_P(obj), obj); } } } -- cgit v1.2.1 From 60b4355168cf3185f87d902be3396265132c045f Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Wed, 14 Oct 2015 12:07:04 +0200 Subject: Do not create a fake Closure for real Closures That is solved by just returning the Closure as is, which is safe due to Closures being immutable objects --- ext/reflection/php_reflection.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'ext/reflection/php_reflection.c') diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index a095120e18..df905bf5cc 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -1762,7 +1762,12 @@ ZEND_METHOD(reflection_function, getClosure) } GET_REFLECTION_OBJECT_PTR(fptr); - zend_create_fake_closure(return_value, fptr, NULL, NULL, NULL); + if (!Z_ISUNDEF(intern->obj)) { + /* Closures are immutable objects */ + ZVAL_COPY(return_value, &intern->obj); + } else { + zend_create_fake_closure(return_value, fptr, NULL, NULL, NULL); + } } /* }}} */ -- cgit v1.2.1 From bbaf6daa9db6e6389181b0cc72175cfa023a398c Mon Sep 17 00:00:00 2001 From: c9s Date: Thu, 22 Oct 2015 20:59:42 +0800 Subject: Fix boolean conversion warnings Summary: The compiler complains and raised some warnings about boolean conversion: warning: address of 'ce->constants_table' will always evaluate to 'true' [-Wpointer-bool-conversion] Since the address of 'HashTable' will always evaluate to true. the condition should be removed. The scope is kept for local variables. Platform: OS X 10.11 Compiler: Apple LLVM version 7.0.0 (clang-700.0.72) Target: x86_64-apple-darwin15.0.0 Thread model: posix --- ext/reflection/php_reflection.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'ext/reflection/php_reflection.c') diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index df905bf5cc..6890d0eeaf 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -445,7 +445,6 @@ static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *in } /* Constants */ - if (&ce->constants_table) { string_printf(str, "\n"); count = zend_hash_num_elements(&ce->constants_table); string_printf(str, "%s - Constants [%d] {\n", indent, count); @@ -459,10 +458,8 @@ static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *in } ZEND_HASH_FOREACH_END(); } string_printf(str, "%s }\n", indent); - } /* Static properties */ - if (&ce->properties_info) { /* counting static properties */ count = zend_hash_num_elements(&ce->properties_info); if (count > 0) { @@ -489,10 +486,8 @@ static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *in } ZEND_HASH_FOREACH_END(); } string_printf(str, "%s }\n", indent); - } /* Static methods */ - if (&ce->function_table) { /* counting static methods */ count = zend_hash_num_elements(&ce->function_table); if (count > 0) { @@ -524,10 +519,8 @@ static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *in string_printf(str, "\n"); } string_printf(str, "%s }\n", indent); - } /* Default/Implicit properties */ - if (&ce->properties_info) { count = zend_hash_num_elements(&ce->properties_info) - count_static_props - count_shadow_props; string_printf(str, "\n%s - Properties [%d] {\n", indent, count); if (count > 0) { @@ -540,7 +533,6 @@ static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *in } ZEND_HASH_FOREACH_END(); } string_printf(str, "%s }\n", indent); - } if (obj && Z_TYPE_P(obj) == IS_OBJECT && Z_OBJ_HT_P(obj)->get_properties) { string dyn; @@ -568,7 +560,6 @@ static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *in } /* Non static methods */ - if (&ce->function_table) { count = zend_hash_num_elements(&ce->function_table) - count_static_funcs; if (count > 0) { zend_function *mptr; @@ -617,7 +608,6 @@ static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *in string_printf(str, "\n%s - Methods [0] {\n", indent); } string_printf(str, "%s }\n", indent); - } string_printf(str, "%s}\n", indent); string_free(&sub_indent); -- cgit v1.2.1 From 95446b441620a1c563249b1c0177b95cf8b32439 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Fri, 23 Oct 2015 11:18:30 +0800 Subject: Indents --- ext/reflection/php_reflection.c | 240 ++++++++++++++++++++-------------------- 1 file changed, 120 insertions(+), 120 deletions(-) (limited to 'ext/reflection/php_reflection.c') diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 6890d0eeaf..faced0572c 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -445,94 +445,94 @@ static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *in } /* Constants */ - string_printf(str, "\n"); - count = zend_hash_num_elements(&ce->constants_table); - string_printf(str, "%s - Constants [%d] {\n", indent, count); - if (count > 0) { - zend_string *key; - zval *value; - - ZEND_HASH_FOREACH_STR_KEY_VAL(&ce->constants_table, key, value) { - zval_update_constant_ex(value, 1, NULL); - _const_string(str, ZSTR_VAL(key), value, indent); - } ZEND_HASH_FOREACH_END(); - } - string_printf(str, "%s }\n", indent); + string_printf(str, "\n"); + count = zend_hash_num_elements(&ce->constants_table); + string_printf(str, "%s - Constants [%d] {\n", indent, count); + if (count > 0) { + zend_string *key; + zval *value; + + ZEND_HASH_FOREACH_STR_KEY_VAL(&ce->constants_table, key, value) { + zval_update_constant_ex(value, 1, NULL); + _const_string(str, ZSTR_VAL(key), value, indent); + } ZEND_HASH_FOREACH_END(); + } + string_printf(str, "%s }\n", indent); /* Static properties */ - /* counting static properties */ - count = zend_hash_num_elements(&ce->properties_info); - if (count > 0) { - zend_property_info *prop; - - ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop) { - if(prop->flags & ZEND_ACC_SHADOW) { - count_shadow_props++; - } else if (prop->flags & ZEND_ACC_STATIC) { - count_static_props++; - } - } ZEND_HASH_FOREACH_END(); - } + /* counting static properties */ + count = zend_hash_num_elements(&ce->properties_info); + if (count > 0) { + zend_property_info *prop; + + ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop) { + if(prop->flags & ZEND_ACC_SHADOW) { + count_shadow_props++; + } else if (prop->flags & ZEND_ACC_STATIC) { + count_static_props++; + } + } ZEND_HASH_FOREACH_END(); + } - /* static properties */ - string_printf(str, "\n%s - Static properties [%d] {\n", indent, count_static_props); - if (count_static_props > 0) { - zend_property_info *prop; + /* static properties */ + string_printf(str, "\n%s - Static properties [%d] {\n", indent, count_static_props); + if (count_static_props > 0) { + zend_property_info *prop; - ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop) { - if ((prop->flags & ZEND_ACC_STATIC) && !(prop->flags & ZEND_ACC_SHADOW)) { - _property_string(str, prop, NULL, ZSTR_VAL(sub_indent.buf)); - } - } ZEND_HASH_FOREACH_END(); - } - string_printf(str, "%s }\n", indent); + ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop) { + if ((prop->flags & ZEND_ACC_STATIC) && !(prop->flags & ZEND_ACC_SHADOW)) { + _property_string(str, prop, NULL, ZSTR_VAL(sub_indent.buf)); + } + } ZEND_HASH_FOREACH_END(); + } + string_printf(str, "%s }\n", indent); /* Static methods */ - /* counting static methods */ - count = zend_hash_num_elements(&ce->function_table); - if (count > 0) { - zend_function *mptr; - - ZEND_HASH_FOREACH_PTR(&ce->function_table, mptr) { - if (mptr->common.fn_flags & ZEND_ACC_STATIC - && ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) == 0 || mptr->common.scope == ce)) - { - count_static_funcs++; - } - } ZEND_HASH_FOREACH_END(); - } + /* counting static methods */ + count = zend_hash_num_elements(&ce->function_table); + if (count > 0) { + zend_function *mptr; + + ZEND_HASH_FOREACH_PTR(&ce->function_table, mptr) { + if (mptr->common.fn_flags & ZEND_ACC_STATIC + && ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) == 0 || mptr->common.scope == ce)) + { + count_static_funcs++; + } + } ZEND_HASH_FOREACH_END(); + } - /* static methods */ - string_printf(str, "\n%s - Static methods [%d] {", indent, count_static_funcs); - if (count_static_funcs > 0) { - zend_function *mptr; + /* static methods */ + string_printf(str, "\n%s - Static methods [%d] {", indent, count_static_funcs); + if (count_static_funcs > 0) { + zend_function *mptr; - ZEND_HASH_FOREACH_PTR(&ce->function_table, mptr) { - if (mptr->common.fn_flags & ZEND_ACC_STATIC - && ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) == 0 || mptr->common.scope == ce)) - { - string_printf(str, "\n"); - _function_string(str, mptr, ce, ZSTR_VAL(sub_indent.buf)); - } - } ZEND_HASH_FOREACH_END(); - } else { - string_printf(str, "\n"); - } - string_printf(str, "%s }\n", indent); + ZEND_HASH_FOREACH_PTR(&ce->function_table, mptr) { + if (mptr->common.fn_flags & ZEND_ACC_STATIC + && ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) == 0 || mptr->common.scope == ce)) + { + string_printf(str, "\n"); + _function_string(str, mptr, ce, ZSTR_VAL(sub_indent.buf)); + } + } ZEND_HASH_FOREACH_END(); + } else { + string_printf(str, "\n"); + } + string_printf(str, "%s }\n", indent); /* Default/Implicit properties */ - count = zend_hash_num_elements(&ce->properties_info) - count_static_props - count_shadow_props; - string_printf(str, "\n%s - Properties [%d] {\n", indent, count); - if (count > 0) { - zend_property_info *prop; - - ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop) { - if (!(prop->flags & (ZEND_ACC_STATIC|ZEND_ACC_SHADOW))) { - _property_string(str, prop, NULL, ZSTR_VAL(sub_indent.buf)); - } - } ZEND_HASH_FOREACH_END(); - } - string_printf(str, "%s }\n", indent); + count = zend_hash_num_elements(&ce->properties_info) - count_static_props - count_shadow_props; + string_printf(str, "\n%s - Properties [%d] {\n", indent, count); + if (count > 0) { + zend_property_info *prop; + + ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop) { + if (!(prop->flags & (ZEND_ACC_STATIC|ZEND_ACC_SHADOW))) { + _property_string(str, prop, NULL, ZSTR_VAL(sub_indent.buf)); + } + } ZEND_HASH_FOREACH_END(); + } + string_printf(str, "%s }\n", indent); if (obj && Z_TYPE_P(obj) == IS_OBJECT && Z_OBJ_HT_P(obj)->get_properties) { string dyn; @@ -560,54 +560,54 @@ static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *in } /* Non static methods */ - count = zend_hash_num_elements(&ce->function_table) - count_static_funcs; - if (count > 0) { - zend_function *mptr; - zend_string *key; - string dyn; - - count = 0; - string_init(&dyn); - - ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->function_table, key, mptr) { - if ((mptr->common.fn_flags & ZEND_ACC_STATIC) == 0 - && ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) == 0 || mptr->common.scope == ce)) - { - size_t len = ZSTR_LEN(mptr->common.function_name); + count = zend_hash_num_elements(&ce->function_table) - count_static_funcs; + if (count > 0) { + zend_function *mptr; + zend_string *key; + string dyn; - /* Do not display old-style inherited constructors */ - if ((mptr->common.fn_flags & ZEND_ACC_CTOR) == 0 - || mptr->common.scope == ce - || !key - || zend_binary_strcasecmp(ZSTR_VAL(key), ZSTR_LEN(key), ZSTR_VAL(mptr->common.function_name), len) == 0) + count = 0; + string_init(&dyn); + + ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->function_table, key, mptr) { + if ((mptr->common.fn_flags & ZEND_ACC_STATIC) == 0 + && ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) == 0 || mptr->common.scope == ce)) + { + size_t len = ZSTR_LEN(mptr->common.function_name); + + /* Do not display old-style inherited constructors */ + if ((mptr->common.fn_flags & ZEND_ACC_CTOR) == 0 + || mptr->common.scope == ce + || !key + || zend_binary_strcasecmp(ZSTR_VAL(key), ZSTR_LEN(key), ZSTR_VAL(mptr->common.function_name), len) == 0) + { + zend_function *closure; + /* see if this is a closure */ + if (ce == zend_ce_closure && obj && (len == sizeof(ZEND_INVOKE_FUNC_NAME)-1) + && memcmp(ZSTR_VAL(mptr->common.function_name), ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0 + && (closure = zend_get_closure_invoke_method(Z_OBJ_P(obj))) != NULL) { - zend_function *closure; - /* see if this is a closure */ - if (ce == zend_ce_closure && obj && (len == sizeof(ZEND_INVOKE_FUNC_NAME)-1) - && memcmp(ZSTR_VAL(mptr->common.function_name), ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0 - && (closure = zend_get_closure_invoke_method(Z_OBJ_P(obj))) != NULL) - { - mptr = closure; - } else { - closure = NULL; - } - string_printf(&dyn, "\n"); - _function_string(&dyn, mptr, ce, ZSTR_VAL(sub_indent.buf)); - count++; - _free_function(closure); + mptr = closure; + } else { + closure = NULL; } + string_printf(&dyn, "\n"); + _function_string(&dyn, mptr, ce, ZSTR_VAL(sub_indent.buf)); + count++; + _free_function(closure); } - } ZEND_HASH_FOREACH_END(); - string_printf(str, "\n%s - Methods [%d] {", indent, count); - if (!count) { - string_printf(str, "\n"); } - string_append(str, &dyn); - string_free(&dyn); - } else { - string_printf(str, "\n%s - Methods [0] {\n", indent); + } ZEND_HASH_FOREACH_END(); + string_printf(str, "\n%s - Methods [%d] {", indent, count); + if (!count) { + string_printf(str, "\n"); } - string_printf(str, "%s }\n", indent); + string_append(str, &dyn); + string_free(&dyn); + } else { + string_printf(str, "\n%s - Methods [0] {\n", indent); + } + string_printf(str, "%s }\n", indent); string_printf(str, "%s}\n", indent); string_free(&sub_indent); -- cgit v1.2.1 From 6cb6c044992414fc8d985c0c24ca6f7a59d2706d Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Fri, 27 Nov 2015 11:32:38 +0800 Subject: Fixed bug #70982 (setStaticPropertyValue behaviors inconsistently with 5.6) --- ext/reflection/php_reflection.c | 1 + 1 file changed, 1 insertion(+) (limited to 'ext/reflection/php_reflection.c') diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index faced0572c..72df8b5901 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -3858,6 +3858,7 @@ ZEND_METHOD(reflection_class, setStaticPropertyValue) "Class %s does not have a property named %s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); return; } + ZVAL_DEREF(variable_ptr); zval_ptr_dtor(variable_ptr); ZVAL_COPY(variable_ptr, value); } -- cgit v1.2.1 From 3ae3341533b68cccaccfc0d78456b72d004dfc80 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Fri, 4 Dec 2015 11:10:07 +0800 Subject: Fixed bug #71018 (ReflectionProperty::setValue() behavior changed) --- ext/reflection/php_reflection.c | 29 +++++++---------------------- 1 file changed, 7 insertions(+), 22 deletions(-) (limited to 'ext/reflection/php_reflection.c') diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 72df8b5901..80001e4997 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -5448,31 +5448,16 @@ ZEND_METHOD(reflection_property, setValue) } variable_ptr = &CE_STATIC_MEMBERS(intern->ce)[ref->prop.offset]; if (variable_ptr != value) { - if (Z_ISREF_P(variable_ptr)) { - zval garbage; + zval garbage; - ZVAL_COPY_VALUE(&garbage, variable_ptr); /* old value should be destroyed */ + ZVAL_DEREF(variable_ptr); + ZVAL_DEREF(value); - /* To check: can't *variable_ptr be some system variable like error_zval here? */ - ZVAL_COPY_VALUE(variable_ptr, value); - if (Z_REFCOUNTED_P(value) && Z_REFCOUNT_P(value) > 0) { - zval_copy_ctor(variable_ptr); - } - zval_dtor(&garbage); - } else { - zval garbage; + ZVAL_COPY_VALUE(&garbage, variable_ptr); - ZVAL_COPY_VALUE(&garbage, variable_ptr); - /* if we assign referenced variable, we should separate it */ - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - if (Z_ISREF_P(value)) { - SEPARATE_ZVAL(value); - } - ZVAL_COPY_VALUE(variable_ptr, value); - zval_ptr_dtor(&garbage); - } + ZVAL_COPY(variable_ptr, value); + + zval_ptr_dtor(&garbage); } } else { const char *class_name, *prop_name; -- cgit v1.2.1 From a75c195000b3226904103244fa9c3d0ce1111838 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 8 Dec 2015 12:40:42 +0300 Subject: Implemented the RFC `Support Class Constant Visibility`. Squashed commit of the following: commit f11ca0e7a57793fa0e3e7f6d451720e6c42bb0b9 Author: Dmitry Stogov Date: Tue Dec 8 12:38:42 2015 +0300 Fixed test expectation commit 211f873f542504d0a0f72b6b5cb23908a1c99a2d Author: Dmitry Stogov Date: Tue Dec 8 12:28:38 2015 +0300 Embed zend_class_constant.flags into zend_class_constants.value.u2.access_flags commit 51deab84b2cdbf9cdb1a838cf33b2ee45c61748b Author: Dmitry Stogov Date: Mon Dec 7 11:18:55 2015 +0300 Fixed issues found by Nikita commit 544dbd5b47e40d38a8ccb96bc5583e9cb7fdd723 Author: Dmitry Stogov Date: Sat Dec 5 02:41:05 2015 +0300 Refactored immplementation of https://wiki.php.net/rfc/class_const_visibility @reeze created an RFC here and I emailed internals here and didn't get any responses positive/negative. --- ext/reflection/php_reflection.c | 348 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 334 insertions(+), 14 deletions(-) (limited to 'ext/reflection/php_reflection.c') diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 80001e4997..51ed11710d 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -64,6 +64,7 @@ PHPAPI zend_class_entry *reflection_class_ptr; PHPAPI zend_class_entry *reflection_object_ptr; PHPAPI zend_class_entry *reflection_method_ptr; PHPAPI zend_class_entry *reflection_property_ptr; +PHPAPI zend_class_entry *reflection_class_constant_ptr; PHPAPI zend_class_entry *reflection_extension_ptr; PHPAPI zend_class_entry *reflection_zend_extension_ptr; @@ -215,7 +216,8 @@ typedef enum { REF_TYPE_PARAMETER, REF_TYPE_TYPE, REF_TYPE_PROPERTY, - REF_TYPE_DYNAMIC_PROPERTY + REF_TYPE_DYNAMIC_PROPERTY, + REF_TYPE_CLASS_CONSTANT } reflection_type_t; /* Struct for reflection objects */ @@ -333,7 +335,7 @@ static void reflection_free_objects_storage(zend_object *object) /* {{{ */ efree(intern->ptr); break; case REF_TYPE_GENERATOR: - break; + case REF_TYPE_CLASS_CONSTANT: case REF_TYPE_OTHER: break; } @@ -368,6 +370,7 @@ static zval *reflection_instantiate(zend_class_entry *pce, zval *object) /* {{{ static void _const_string(string *str, char *name, zval *value, char *indent); static void _function_string(string *str, zend_function *fptr, zend_class_entry *scope, char* indent); static void _property_string(string *str, zend_property_info *prop, char *prop_name, char* indent); +static void _class_const_string(string *str, char *name, zend_class_constant *c, char* indent); static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *indent); static void _extension_string(string *str, zend_module_entry *module, char *indent); static void _zend_extension_string(string *str, zend_extension *extension, char *indent); @@ -450,11 +453,11 @@ static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *in string_printf(str, "%s - Constants [%d] {\n", indent, count); if (count > 0) { zend_string *key; - zval *value; + zend_class_constant *c; - ZEND_HASH_FOREACH_STR_KEY_VAL(&ce->constants_table, key, value) { - zval_update_constant_ex(value, 1, NULL); - _const_string(str, ZSTR_VAL(key), value, indent); + ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->constants_table, key, c) { + zval_update_constant_ex(&c->value, 1, NULL); + _class_const_string(str, ZSTR_VAL(key), c, indent); } ZEND_HASH_FOREACH_END(); } string_printf(str, "%s }\n", indent); @@ -627,6 +630,20 @@ 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); + + string_printf(str, "%s Constant [ %s %s %s ] { %s }\n", + indent, visibility, type, name, ZSTR_VAL(value_str)); + + zend_string_release(value_str); +} +/* }}} */ + /* {{{ _get_recv_opcode */ static zend_op* _get_recv_op(zend_op_array *op_array, uint32_t offset) { @@ -1356,6 +1373,27 @@ static void reflection_property_factory(zend_class_entry *ce, zend_property_info } /* }}} */ +/* {{{ reflection_class_constant_factory */ +static void reflection_class_constant_factory(zend_class_entry *ce, zend_string *name_str, zend_class_constant *constant, zval *object) +{ + reflection_object *intern; + zval name; + zval classname; + + ZVAL_STR_COPY(&name, name_str); + ZVAL_STR_COPY(&classname, ce->name); + + reflection_instantiate(reflection_class_constant_ptr, object); + intern = Z_REFLECTION_P(object); + intern->ptr = constant; + intern->ref_type = REF_TYPE_CLASS_CONSTANT; + intern->ce = constant->ce; + intern->ignore_visibility = 0; + reflection_update_property(object, "name", &name); + reflection_update_property(object, "class", &classname); +} +/* }}} */ + /* {{{ _reflection_export */ static void _reflection_export(INTERNAL_FUNCTION_PARAMETERS, zend_class_entry *ce_ptr, int ctor_argc) { @@ -3668,6 +3706,197 @@ ZEND_METHOD(reflection_method, setAccessible) } /* }}} */ +/* {{{ proto public void ReflectionClassConstant::__construct(mixed class, string name) + Constructor. Throws an Exception in case the given class constant does not exist */ +ZEND_METHOD(reflection_class_constant, __construct) +{ + zval *classname, *object, name, cname; + zend_string *constname; + reflection_object *intern; + zend_class_entry *ce; + zend_class_constant *constant = NULL; + + if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "zS", &classname, &constname) == FAILURE) { + return; + } + + object = getThis(); + intern = Z_REFLECTION_P(object); + if (intern == NULL) { + return; + } + + /* Find the class entry */ + switch (Z_TYPE_P(classname)) { + case IS_STRING: + if ((ce = zend_lookup_class(Z_STR_P(classname))) == NULL) { + zend_throw_exception_ex(reflection_exception_ptr, 0, + "Class %s does not exist", Z_STRVAL_P(classname)); + return; + } + break; + + case IS_OBJECT: + ce = Z_OBJCE_P(classname); + break; + + default: + _DO_THROW("The parameter class is expected to be either a string or an object"); + /* returns out of this function */ + } + + if ((constant = zend_hash_find_ptr(&ce->constants_table, constname)) == NULL) { + zend_throw_exception_ex(reflection_exception_ptr, 0, "Class Constant %s::%s does not exist", ZSTR_VAL(ce->name), ZSTR_VAL(constname)); + return; + } + + ZVAL_STR_COPY(&name, constname); + ZVAL_STR_COPY(&cname, ce->name); + + intern->ptr = constant; + intern->ref_type = REF_TYPE_CLASS_CONSTANT; + intern->ce = constant->ce; + intern->ignore_visibility = 0; + reflection_update_property(object, "name", &name); + reflection_update_property(object, "class", &cname); +} +/* }}} */ + +/* {{{ proto public string ReflectionClassConstant::__toString() + Returns a string representation */ +ZEND_METHOD(reflection_class_constant, __toString) +{ + reflection_object *intern; + zend_class_constant *ref; + string str; + zval name; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(ref); + string_init(&str); + _default_get_entry(getThis(), "name", sizeof("name")-1, &name); + _class_const_string(&str, Z_STRVAL(name), ref, ""); + zval_ptr_dtor(&name); + RETURN_NEW_STR(str.buf); +} +/* }}} */ + +/* {{{ proto public string ReflectionClassConstant::getName() + Returns the constant' name */ +ZEND_METHOD(reflection_class_constant, getName) +{ + if (zend_parse_parameters_none() == FAILURE) { + return; + } + _default_get_entry(getThis(), "name", sizeof("name")-1, return_value); +} +/* }}} */ + +static void _class_constant_check_flag(INTERNAL_FUNCTION_PARAMETERS, int mask) /* {{{ */ +{ + reflection_object *intern; + zend_class_constant *ref; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(ref); + RETURN_BOOL(Z_ACCESS_FLAGS(ref->value) & mask); +} +/* }}} */ + +/* {{{ proto public bool ReflectionClassConstant::isPublic() + Returns whether this constant is public */ +ZEND_METHOD(reflection_class_constant, isPublic) +{ + _class_constant_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PUBLIC | ZEND_ACC_IMPLICIT_PUBLIC); +} +/* }}} */ + +/* {{{ proto public bool ReflectionClassConstant::isPrivate() + Returns whether this constant is private */ +ZEND_METHOD(reflection_class_constant, isPrivate) +{ + _class_constant_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PRIVATE); +} +/* }}} */ + +/* {{{ proto public bool ReflectionClassConstant::isProtected() + Returns whether this constant is protected */ +ZEND_METHOD(reflection_class_constant, isProtected) +{ + _class_constant_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PROTECTED); +} +/* }}} */ + +/* {{{ proto public int ReflectionClassConstant::getModifiers() + Returns a bitfield of the access modifiers for this constant */ +ZEND_METHOD(reflection_class_constant, getModifiers) +{ + reflection_object *intern; + zend_class_constant *ref; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(ref); + + RETURN_LONG(Z_ACCESS_FLAGS(ref->value)); +} +/* }}} */ + +/* {{{ proto public mixed ReflectionClassConstant::getValue() + Returns this constant's value */ +ZEND_METHOD(reflection_class_constant, getValue) +{ + reflection_object *intern; + zend_class_constant *ref; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(ref); + + ZVAL_DUP(return_value, &ref->value); +} +/* }}} */ + +/* {{{ proto public ReflectionClass ReflectionClassConstant::getDeclaringClass() + Get the declaring class */ +ZEND_METHOD(reflection_class_constant, getDeclaringClass) +{ + reflection_object *intern; + zend_class_constant *ref; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(ref); + + zend_reflection_class_factory(ref->ce, return_value); +} +/* }}} */ + +/* {{{ proto public string ReflectionClassConstant::getDocComment() + Returns the doc comment for this constant */ +ZEND_METHOD(reflection_class_constant, getDocComment) +{ + reflection_object *intern; + zend_class_constant *ref; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(ref); + if (ref->doc_comment) { + RETURN_STR_COPY(ref->doc_comment); + } + RETURN_FALSE; +} +/* }}} */ + /* {{{ proto public static mixed ReflectionClass::export(mixed argument [, bool return]) throws ReflectionException Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */ ZEND_METHOD(reflection_class, export) @@ -4414,6 +4643,8 @@ ZEND_METHOD(reflection_class, getConstants) { reflection_object *intern; zend_class_entry *ce; + zend_string *key; + zend_class_constant *c; zval *val; if (zend_parse_parameters_none() == FAILURE) { @@ -4421,12 +4652,36 @@ ZEND_METHOD(reflection_class, getConstants) } GET_REFLECTION_OBJECT_PTR(ce); array_init(return_value); - ZEND_HASH_FOREACH_VAL(&ce->constants_table, val) { - if (UNEXPECTED(zval_update_constant_ex(val, 1, ce) != SUCCESS)) { + ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->constants_table, key, c) { + if (UNEXPECTED(zval_update_constant_ex(&c->value, 1, ce) != SUCCESS)) { + zend_array_destroy(Z_ARRVAL_P(return_value)); return; } + val = zend_hash_add_new(Z_ARRVAL_P(return_value), key, &c->value); + Z_TRY_ADDREF_P(val); + } ZEND_HASH_FOREACH_END(); +} +/* }}} */ + +/* {{{ proto public array ReflectionClass::getReflectionConstants() + Returns an associative array containing this class' constants as ReflectionClassConstant objects */ +ZEND_METHOD(reflection_class, getReflectionConstants) +{ + reflection_object *intern; + zend_class_entry *ce; + zend_string *name; + zend_class_constant *constant; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(ce); + array_init(return_value); + ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->constants_table, name, constant) { + zval class_const; + reflection_class_constant_factory(ce, name, constant, &class_const); + zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &class_const); } ZEND_HASH_FOREACH_END(); - zend_hash_copy(Z_ARRVAL_P(return_value), &ce->constants_table, zval_add_ref_unref); } /* }}} */ @@ -4436,7 +4691,7 @@ ZEND_METHOD(reflection_class, getConstant) { reflection_object *intern; zend_class_entry *ce; - zval *value; + zend_class_constant *c; zend_string *name; METHOD_NOTSTATIC(reflection_class_ptr); @@ -4445,15 +4700,36 @@ ZEND_METHOD(reflection_class, getConstant) } GET_REFLECTION_OBJECT_PTR(ce); - ZEND_HASH_FOREACH_VAL(&ce->constants_table, value) { - if (UNEXPECTED(zval_update_constant_ex(value, 1, ce) != SUCCESS)) { + ZEND_HASH_FOREACH_PTR(&ce->constants_table, c) { + if (UNEXPECTED(zval_update_constant_ex(&c->value, 1, ce) != SUCCESS)) { return; } } ZEND_HASH_FOREACH_END(); - if ((value = zend_hash_find(&ce->constants_table, name)) == NULL) { + if ((c = zend_hash_find_ptr(&ce->constants_table, name)) == NULL) { RETURN_FALSE; } - ZVAL_DUP(return_value, value); + ZVAL_DUP(return_value, &c->value); +} +/* }}} */ + +/* {{{ proto public mixed ReflectionClass::getReflectionConstant(string name) + Returns the class' constant as ReflectionClassConstant objects */ +ZEND_METHOD(reflection_class, getReflectionConstant) +{ + reflection_object *intern; + zend_class_entry *ce; + zend_class_constant *constant; + zend_string *name; + + GET_REFLECTION_OBJECT_PTR(ce); + if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &name) == FAILURE) { + return; + } + + if ((constant = zend_hash_find_ptr(&ce->constants_table, name)) == NULL) { + RETURN_FALSE; + } + reflection_class_constant_factory(ce, name, constant, return_value); } /* }}} */ @@ -5171,6 +5447,14 @@ ZEND_METHOD(reflection_property, export) } /* }}} */ +/* {{{ proto public static mixed ReflectionClassConstant::export(mixed class, string name [, bool return]) throws ReflectionException + Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */ +ZEND_METHOD(reflection_class_constant, export) +{ + _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_class_constant_ptr, 2); +} +/* }}} */ + /* {{{ proto public void ReflectionProperty::__construct(mixed class, string name) Constructor. Throws an Exception in case the given property does not exist */ ZEND_METHOD(reflection_property, __construct) @@ -6334,7 +6618,9 @@ static const zend_function_entry reflection_class_functions[] = { ZEND_ME(reflection_class, getProperties, arginfo_reflection_class_getProperties, 0) ZEND_ME(reflection_class, hasConstant, arginfo_reflection_class_hasConstant, 0) ZEND_ME(reflection_class, getConstants, arginfo_reflection__void, 0) + ZEND_ME(reflection_class, getReflectionConstants, arginfo_reflection__void, 0) ZEND_ME(reflection_class, getConstant, arginfo_reflection_class_getConstant, 0) + ZEND_ME(reflection_class, getReflectionConstant, arginfo_reflection_class_getConstant, 0) ZEND_ME(reflection_class, getInterfaces, arginfo_reflection__void, 0) ZEND_ME(reflection_class, getInterfaceNames, arginfo_reflection__void, 0) ZEND_ME(reflection_class, isInterface, arginfo_reflection__void, 0) @@ -6426,6 +6712,33 @@ static const zend_function_entry reflection_property_functions[] = { PHP_FE_END }; +ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_class_constant_export, 0, 0, 2) + ZEND_ARG_INFO(0, class) + ZEND_ARG_INFO(0, name) + ZEND_ARG_INFO(0, return) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_class_constant___construct, 0, 0, 2) + ZEND_ARG_INFO(0, class) + ZEND_ARG_INFO(0, name) +ZEND_END_ARG_INFO() + +static const zend_function_entry reflection_class_constant_functions[] = { + ZEND_ME(reflection, __clone, arginfo_reflection__void, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL) + ZEND_ME(reflection_class_constant, export, arginfo_reflection_class_constant_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC) + ZEND_ME(reflection_class_constant, __construct, arginfo_reflection_class_constant___construct, 0) + ZEND_ME(reflection_class_constant, __toString, arginfo_reflection__void, 0) + ZEND_ME(reflection_class_constant, getName, arginfo_reflection__void, 0) + ZEND_ME(reflection_class_constant, getValue, arginfo_reflection__void, 0) + ZEND_ME(reflection_class_constant, isPublic, arginfo_reflection__void, 0) + ZEND_ME(reflection_class_constant, isPrivate, arginfo_reflection__void, 0) + ZEND_ME(reflection_class_constant, isProtected, arginfo_reflection__void, 0) + ZEND_ME(reflection_class_constant, getModifiers, arginfo_reflection__void, 0) + ZEND_ME(reflection_class_constant, getDeclaringClass, arginfo_reflection__void, 0) + ZEND_ME(reflection_class_constant, getDocComment, arginfo_reflection__void, 0) + PHP_FE_END +}; + ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_parameter_export, 0, 0, 2) ZEND_ARG_INFO(0, function) ZEND_ARG_INFO(0, parameter) @@ -6622,6 +6935,13 @@ PHP_MINIT_FUNCTION(reflection) /* {{{ */ 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_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); + zend_declare_property_string(reflection_class_constant_ptr, "class", sizeof("class")-1, "", ZEND_ACC_PUBLIC); + REGISTER_REFLECTION_CLASS_CONST_LONG(property, "IS_STATIC", ZEND_ACC_STATIC); REGISTER_REFLECTION_CLASS_CONST_LONG(property, "IS_PUBLIC", ZEND_ACC_PUBLIC); REGISTER_REFLECTION_CLASS_CONST_LONG(property, "IS_PROTECTED", ZEND_ACC_PROTECTED); -- cgit v1.2.1 From c58b0cb4ceb26d96c2088b80e98c6cbc6b3971bd Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 8 Dec 2015 12:47:05 +0300 Subject: Removed useless checks --- ext/reflection/php_reflection.c | 43 ++++------------------------------------- 1 file changed, 4 insertions(+), 39 deletions(-) (limited to 'ext/reflection/php_reflection.c') diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 51ed11710d..21205b5624 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -105,7 +105,7 @@ ZEND_DECLARE_MODULE_GLOBALS(reflection) #define GET_REFLECTION_OBJECT() \ intern = Z_REFLECTION_P(getThis()); \ - if (intern == NULL || intern->ptr == NULL) { \ + if (intern->ptr == NULL) { \ RETURN_ON_EXCEPTION \ php_error_docref(NULL, E_ERROR, "Internal error: Failed to retrieve the reflection object"); \ } \ @@ -1497,7 +1497,7 @@ static parameter_reference *_reflection_param_get_default_param(INTERNAL_FUNCTIO parameter_reference *param; intern = Z_REFLECTION_P(getThis()); - if (intern == NULL || intern->ptr == NULL) { + if (intern->ptr == NULL) { if (EG(exception) && EG(exception)->ce == reflection_exception_ptr) { return NULL; } @@ -1651,9 +1651,6 @@ ZEND_METHOD(reflection_function, __construct) object = getThis(); intern = Z_REFLECTION_P(object); - if (intern == NULL) { - return; - } if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "O", &closure, zend_ce_closure) == SUCCESS) { fptr = (zend_function*)zend_get_closure_method_def(closure); @@ -2195,9 +2192,6 @@ ZEND_METHOD(reflection_generator, __construct) object = getThis(); intern = Z_REFLECTION_P(object); - if (intern == NULL) { - return; - } if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "O", &generator, zend_ce_generator) == FAILURE) { return; @@ -2384,9 +2378,6 @@ ZEND_METHOD(reflection_parameter, __construct) object = getThis(); intern = Z_REFLECTION_P(object); - if (intern == NULL) { - return; - } /* First, find the function */ switch (Z_TYPE_P(reference)) { @@ -3089,9 +3080,6 @@ ZEND_METHOD(reflection_method, __construct) object = getThis(); intern = Z_REFLECTION_P(object); - if (intern == NULL) { - return; - } /* Find the class entry */ switch (Z_TYPE_P(classname)) { @@ -3698,10 +3686,6 @@ ZEND_METHOD(reflection_method, setAccessible) intern = Z_REFLECTION_P(getThis()); - if (intern == NULL) { - return; - } - intern->ignore_visibility = visible; } /* }}} */ @@ -3722,9 +3706,6 @@ ZEND_METHOD(reflection_class_constant, __construct) object = getThis(); intern = Z_REFLECTION_P(object); - if (intern == NULL) { - return; - } /* Find the class entry */ switch (Z_TYPE_P(classname)) { @@ -3926,9 +3907,6 @@ static void reflection_class_object_ctor(INTERNAL_FUNCTION_PARAMETERS, int is_ob object = getThis(); intern = Z_REFLECTION_P(object); - if (intern == NULL) { - return; - } if (Z_TYPE_P(argument) == IS_OBJECT) { ZVAL_STR_COPY(&classname, Z_OBJCE_P(argument)->name); @@ -5226,7 +5204,7 @@ ZEND_METHOD(reflection_class, isSubclassOf) case IS_OBJECT: if (instanceof_function(Z_OBJCE_P(class_name), reflection_class_ptr)) { argument = Z_REFLECTION_P(class_name); - if (argument == NULL || argument->ptr == NULL) { + if (argument->ptr == NULL) { php_error_docref(NULL, E_ERROR, "Internal error: Failed to retrieve the argument's reflection object"); /* Bails out */ } @@ -5270,7 +5248,7 @@ ZEND_METHOD(reflection_class, implementsInterface) case IS_OBJECT: if (instanceof_function(Z_OBJCE_P(interface), reflection_class_ptr)) { argument = Z_REFLECTION_P(interface); - if (argument == NULL || argument->ptr == NULL) { + if (argument->ptr == NULL) { php_error_docref(NULL, E_ERROR, "Internal error: Failed to retrieve the argument's reflection object"); /* Bails out */ } @@ -5475,9 +5453,6 @@ ZEND_METHOD(reflection_property, __construct) object = getThis(); intern = Z_REFLECTION_P(object); - if (intern == NULL) { - return; - } /* Find the class entry */ switch (Z_TYPE_P(classname)) { @@ -5826,10 +5801,6 @@ ZEND_METHOD(reflection_property, setAccessible) intern = Z_REFLECTION_P(getThis()); - if (intern == NULL) { - return; - } - intern->ignore_visibility = visible; } /* }}} */ @@ -5861,9 +5832,6 @@ ZEND_METHOD(reflection_extension, __construct) object = getThis(); intern = Z_REFLECTION_P(object); - if (intern == NULL) { - return; - } lcname = do_alloca(name_len + 1, use_heap); zend_str_tolower_copy(lcname, name_str, name_len); if ((module = zend_hash_str_find_ptr(&module_registry, lcname, name_len)) == NULL) { @@ -6229,9 +6197,6 @@ ZEND_METHOD(reflection_zend_extension, __construct) object = getThis(); intern = Z_REFLECTION_P(object); - if (intern == NULL) { - return; - } extension = zend_get_extension(name_str); if (!extension) { -- cgit v1.2.1 From 0adbf6de774d9b1938a34b969c40ea2ac1982222 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Wed, 9 Dec 2015 11:37:40 +0800 Subject: Remove useless check --- ext/reflection/php_reflection.c | 37 +++---------------------------------- 1 file changed, 3 insertions(+), 34 deletions(-) (limited to 'ext/reflection/php_reflection.c') diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 80001e4997..b81ce75525 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -104,7 +104,7 @@ ZEND_DECLARE_MODULE_GLOBALS(reflection) #define GET_REFLECTION_OBJECT() \ intern = Z_REFLECTION_P(getThis()); \ - if (intern == NULL || intern->ptr == NULL) { \ + if (intern->ptr == NULL) { \ RETURN_ON_EXCEPTION \ php_error_docref(NULL, E_ERROR, "Internal error: Failed to retrieve the reflection object"); \ } \ @@ -1459,7 +1459,7 @@ static parameter_reference *_reflection_param_get_default_param(INTERNAL_FUNCTIO parameter_reference *param; intern = Z_REFLECTION_P(getThis()); - if (intern == NULL || intern->ptr == NULL) { + if (intern->ptr == NULL) { if (EG(exception) && EG(exception)->ce == reflection_exception_ptr) { return NULL; } @@ -1613,9 +1613,6 @@ ZEND_METHOD(reflection_function, __construct) object = getThis(); intern = Z_REFLECTION_P(object); - if (intern == NULL) { - return; - } if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "O", &closure, zend_ce_closure) == SUCCESS) { fptr = (zend_function*)zend_get_closure_method_def(closure); @@ -2157,9 +2154,6 @@ ZEND_METHOD(reflection_generator, __construct) object = getThis(); intern = Z_REFLECTION_P(object); - if (intern == NULL) { - return; - } if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "O", &generator, zend_ce_generator) == FAILURE) { return; @@ -2346,9 +2340,6 @@ ZEND_METHOD(reflection_parameter, __construct) object = getThis(); intern = Z_REFLECTION_P(object); - if (intern == NULL) { - return; - } /* First, find the function */ switch (Z_TYPE_P(reference)) { @@ -3051,9 +3042,6 @@ ZEND_METHOD(reflection_method, __construct) object = getThis(); intern = Z_REFLECTION_P(object); - if (intern == NULL) { - return; - } /* Find the class entry */ switch (Z_TYPE_P(classname)) { @@ -3660,10 +3648,6 @@ ZEND_METHOD(reflection_method, setAccessible) intern = Z_REFLECTION_P(getThis()); - if (intern == NULL) { - return; - } - intern->ignore_visibility = visible; } /* }}} */ @@ -3697,9 +3681,6 @@ static void reflection_class_object_ctor(INTERNAL_FUNCTION_PARAMETERS, int is_ob object = getThis(); intern = Z_REFLECTION_P(object); - if (intern == NULL) { - return; - } if (Z_TYPE_P(argument) == IS_OBJECT) { ZVAL_STR_COPY(&classname, Z_OBJCE_P(argument)->name); @@ -5191,9 +5172,6 @@ ZEND_METHOD(reflection_property, __construct) object = getThis(); intern = Z_REFLECTION_P(object); - if (intern == NULL) { - return; - } /* Find the class entry */ switch (Z_TYPE_P(classname)) { @@ -5542,10 +5520,6 @@ ZEND_METHOD(reflection_property, setAccessible) intern = Z_REFLECTION_P(getThis()); - if (intern == NULL) { - return; - } - intern->ignore_visibility = visible; } /* }}} */ @@ -5577,9 +5551,7 @@ ZEND_METHOD(reflection_extension, __construct) object = getThis(); intern = Z_REFLECTION_P(object); - if (intern == NULL) { - return; - } + lcname = do_alloca(name_len + 1, use_heap); zend_str_tolower_copy(lcname, name_str, name_len); if ((module = zend_hash_str_find_ptr(&module_registry, lcname, name_len)) == NULL) { @@ -5945,9 +5917,6 @@ ZEND_METHOD(reflection_zend_extension, __construct) object = getThis(); intern = Z_REFLECTION_P(object); - if (intern == NULL) { - return; - } extension = zend_get_extension(name_str); if (!extension) { -- cgit v1.2.1 From 49493a2dcfb2cd1758b69b13d9006ead3be0e066 Mon Sep 17 00:00:00 2001 From: Lior Kaplan Date: Fri, 1 Jan 2016 19:19:27 +0200 Subject: Happy new year (Update copyright to 2016) --- 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 e1a2c57668..fbcf7a77ca 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2015 The PHP Group | + | Copyright (c) 1997-2016 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | -- cgit v1.2.1 From b899656eb0bd3d56caf8adebeef0ab3b2421e413 Mon Sep 17 00:00:00 2001 From: Joe Watkins Date: Wed, 20 Jan 2016 10:52:27 +0000 Subject: fix ReflectionClass::__toString doc block omitted --- 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 b81ce75525..8e6a3c0d71 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -383,7 +383,7 @@ static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *in /* TBD: Repair indenting of doc comment (or is this to be done in the parser?) */ if (ce->type == ZEND_USER_CLASS && ce->info.user.doc_comment) { - string_printf(str, "%s%s", indent, ce->info.user.doc_comment); + string_printf(str, "%s%s", indent, ZSTR_VAL(ce->info.user.doc_comment)); string_write(str, "\n", 1); } -- cgit v1.2.1 From 11cf826b8960f0d9af5368b1af90ac3f81947f16 Mon Sep 17 00:00:00 2001 From: Joe Watkins Date: Wed, 20 Jan 2016 10:52:27 +0000 Subject: fix ReflectionClass::__toString doc block omitted --- 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 7713137e89..461104f394 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -386,7 +386,7 @@ static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *in /* TBD: Repair indenting of doc comment (or is this to be done in the parser?) */ if (ce->type == ZEND_USER_CLASS && ce->info.user.doc_comment) { - string_printf(str, "%s%s", indent, ce->info.user.doc_comment); + string_printf(str, "%s%s", indent, ZSTR_VAL(ce->info.user.doc_comment)); string_write(str, "\n", 1); } -- cgit v1.2.1 From 8412de9da5304ca0ea287277c7e0d916e2c490be Mon Sep 17 00:00:00 2001 From: Andrea Faulds Date: Thu, 28 Jan 2016 18:01:48 +0000 Subject: Support void return type in reflection --- ext/reflection/php_reflection.c | 1 + 1 file changed, 1 insertion(+) (limited to 'ext/reflection/php_reflection.c') diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 461104f394..af1e972f60 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -3029,6 +3029,7 @@ ZEND_METHOD(reflection_type, __toString) case _IS_BOOL: RETURN_STRINGL("bool", sizeof("bool") - 1); case IS_LONG: RETURN_STRINGL("int", sizeof("int") - 1); case IS_DOUBLE: RETURN_STRINGL("float", sizeof("float") - 1); + case IS_VOID: RETURN_STRINGL("void", sizeof("void") - 1); EMPTY_SWITCH_DEFAULT_CASE() } } -- cgit v1.2.1 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