From: Johannes Schlüter Date: Wed, 18 Oct 2006 16:34:25 +0000 (+0000) Subject: - Fix #38465 (ReflectionParameter fails if default value is an access to self:: X-Git-Tag: RELEASE_1_0_0RC1~1256 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0e58baae93579c2314753b1ddfd5824443d44186;p=php - Fix #38465 (ReflectionParameter fails if default value is an access to self:: --- diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index 68a52e3760..3c90193a05 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -585,7 +585,7 @@ ZEND_FUNCTION(defined) } convert_to_text_ex(var); - if (zend_u_get_constant(Z_TYPE_PP(var), Z_UNIVAL_PP(var), Z_UNILEN_PP(var), &c TSRMLS_CC)) { + if (zend_u_get_constant(Z_TYPE_PP(var), Z_UNIVAL_PP(var), Z_UNILEN_PP(var), &c, NULL TSRMLS_CC)) { zval_dtor(&c); RETURN_TRUE; } else { diff --git a/Zend/zend_constants.c b/Zend/zend_constants.c index 089ef6d93b..eac88543c0 100644 --- a/Zend/zend_constants.c +++ b/Zend/zend_constants.c @@ -231,7 +231,7 @@ ZEND_API void zend_register_string_constant(char *name, uint name_len, char *str } -ZEND_API int zend_u_get_constant(zend_uchar type, zstr name, uint name_len, zval *result TSRMLS_DC) +ZEND_API int zend_u_get_constant(zend_uchar type, zstr name, uint name_len, zval *result, zend_class_entry *scope TSRMLS_DC) { zend_constant *c; int retval = 1; @@ -241,7 +241,7 @@ ZEND_API int zend_u_get_constant(zend_uchar type, zstr name, uint name_len, zval if ((UG(unicode) && (colon.u = u_memchr(name.u, ':', name_len)) && colon.u[1] == ':') || (!UG(unicode) && (colon.s = memchr(name.s, ':', name_len)) && colon.s[1] == ':')) { /* class constant */ - zend_class_entry **ce = NULL, *scope; + zend_class_entry **ce = NULL; int class_name_len = UG(unicode)?colon.u-name.u:colon.s-name.s; int const_name_len = name_len - class_name_len - 2; zstr constant_name, class_name; @@ -253,10 +253,12 @@ ZEND_API int zend_u_get_constant(zend_uchar type, zstr name, uint name_len, zval constant_name.s = colon.s + 2; } - if (EG(in_execution)) { - scope = EG(scope); - } else { - scope = CG(active_class_entry); + if (!scope) { + if (EG(in_execution)) { + scope = EG(scope); + } else { + scope = CG(active_class_entry); + } } if (UG(unicode)) { @@ -333,7 +335,7 @@ ZEND_API int zend_u_get_constant(zend_uchar type, zstr name, uint name_len, zval ZEND_API int zend_get_constant(char *name, uint name_len, zval *result TSRMLS_DC) { - return zend_u_get_constant(IS_STRING, ZSTR(name), name_len, result TSRMLS_CC); + return zend_u_get_constant(IS_STRING, ZSTR(name), name_len, result, NULL TSRMLS_CC); } ZEND_API int zend_u_register_constant(zend_uchar type, zend_constant *c TSRMLS_DC) diff --git a/Zend/zend_constants.h b/Zend/zend_constants.h index 319a3b9bf2..79e5e30be6 100644 --- a/Zend/zend_constants.h +++ b/Zend/zend_constants.h @@ -56,7 +56,7 @@ int zend_shutdown_constants(TSRMLS_D); void zend_register_standard_constants(TSRMLS_D); void clean_non_persistent_constants(TSRMLS_D); ZEND_API int zend_get_constant(char *name, uint name_len, zval *result TSRMLS_DC); -ZEND_API int zend_u_get_constant(zend_uchar type, zstr name, uint name_len, zval *result TSRMLS_DC); +ZEND_API int zend_u_get_constant(zend_uchar type, zstr name, uint name_len, zval *result, zend_class_entry *scope TSRMLS_DC); ZEND_API void zend_register_long_constant(char *name, uint name_len, long lval, int flags, int module_number TSRMLS_DC); ZEND_API void zend_register_double_constant(char *name, uint name_len, double dval, int flags, int module_number TSRMLS_DC); ZEND_API void zend_register_string_constant(char *name, uint name_len, char *strval, int flags, int module_number TSRMLS_DC); diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h index 787467b761..ecf4228f33 100644 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@ -143,6 +143,7 @@ static inline int i_zend_is_true(zval *op) } ZEND_API int zval_update_constant(zval **pp, void *arg TSRMLS_DC); +ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *scope TSRMLS_DC); /* dedicated Zend executor functions - do not use! */ static inline void zend_ptr_stack_clear_multiple(TSRMLS_D) diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index dc53e2ac47..7f8eb7b326 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -469,7 +469,7 @@ ZEND_API int zend_is_true(zval *op) #include "../TSRM/tsrm_strtok_r.h" -ZEND_API int zval_update_constant(zval **pp, void *arg TSRMLS_DC) +ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *scope TSRMLS_DC) { zval *p = *pp; zend_bool inline_change = (zend_bool) (unsigned long) arg; @@ -485,7 +485,7 @@ ZEND_API int zval_update_constant(zval **pp, void *arg TSRMLS_DC) refcount = p->refcount; is_ref = p->is_ref; - if (!zend_u_get_constant(UG(unicode)?IS_UNICODE:IS_STRING, Z_UNIVAL_P(p), Z_UNILEN_P(p), &const_value TSRMLS_CC)) { + if (!zend_u_get_constant(ZEND_STR_TYPE, Z_UNIVAL_P(p), Z_UNILEN_P(p), &const_value, scope TSRMLS_CC)) { zend_error(E_NOTICE, "Use of undefined constant %v - assumed '%v'", Z_UNIVAL_P(p), Z_UNIVAL_P(p)); @@ -524,7 +524,7 @@ ZEND_API int zval_update_constant(zval **pp, void *arg TSRMLS_DC) zend_hash_move_forward(Z_ARRVAL_P(p)); continue; } - if (!zend_u_get_constant(UG(unicode)?IS_UNICODE:IS_STRING, str_index, str_index_len-1, &const_value TSRMLS_CC)) { + if (!zend_u_get_constant(ZEND_STR_TYPE, str_index, str_index_len-1, &const_value, scope TSRMLS_CC)) { zend_error(E_NOTICE, "Use of undefined constant %v - assumed '%v'", str_index, str_index); zend_hash_move_forward(Z_ARRVAL_P(p)); continue; @@ -586,6 +586,10 @@ ZEND_API int zval_update_constant(zval **pp, void *arg TSRMLS_DC) return 0; } +ZEND_API int zval_update_constant(zval **pp, void *arg TSRMLS_DC) +{ + zval_update_constant_ex(pp, arg, NULL TSRMLS_CC); +} int call_user_function(HashTable *function_table, zval **object_pp, zval *function_name, zval *retval_ptr, zend_uint param_count, zval *params[] TSRMLS_DC) { diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index b9ce080a89..fc398d7b69 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -2617,7 +2617,7 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, CONST|UNUSED, CONST) } } */ - if (!zend_u_get_constant(Z_TYPE(opline->op2.u.constant), Z_UNIVAL(opline->op2.u.constant), Z_UNILEN(opline->op2.u.constant), &EX_T(opline->result.u.var).tmp_var TSRMLS_CC)) { + if (!zend_u_get_constant(Z_TYPE(opline->op2.u.constant), Z_UNIVAL(opline->op2.u.constant), Z_UNILEN(opline->op2.u.constant), &EX_T(opline->result.u.var).tmp_var, NULL TSRMLS_CC)) { zend_error(E_NOTICE, "Use of undefined constant %R - assumed '%R'", Z_TYPE(opline->op2.u.constant), Z_UNIVAL(opline->op2.u.constant), diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index b39cfbafb8..d31a89159b 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -2670,7 +2670,7 @@ static int ZEND_FETCH_CONSTANT_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS } } */ - if (!zend_u_get_constant(Z_TYPE(opline->op2.u.constant), Z_UNIVAL(opline->op2.u.constant), Z_UNILEN(opline->op2.u.constant), &EX_T(opline->result.u.var).tmp_var TSRMLS_CC)) { + if (!zend_u_get_constant(Z_TYPE(opline->op2.u.constant), Z_UNIVAL(opline->op2.u.constant), Z_UNILEN(opline->op2.u.constant), &EX_T(opline->result.u.var).tmp_var, NULL TSRMLS_CC)) { zend_error(E_NOTICE, "Use of undefined constant %R - assumed '%R'", Z_TYPE(opline->op2.u.constant), Z_UNIVAL(opline->op2.u.constant), @@ -15807,7 +15807,7 @@ static int ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG } } */ - if (!zend_u_get_constant(Z_TYPE(opline->op2.u.constant), Z_UNIVAL(opline->op2.u.constant), Z_UNILEN(opline->op2.u.constant), &EX_T(opline->result.u.var).tmp_var TSRMLS_CC)) { + if (!zend_u_get_constant(Z_TYPE(opline->op2.u.constant), Z_UNIVAL(opline->op2.u.constant), Z_UNILEN(opline->op2.u.constant), &EX_T(opline->result.u.var).tmp_var, NULL TSRMLS_CC)) { zend_error(E_NOTICE, "Use of undefined constant %R - assumed '%R'", Z_TYPE(opline->op2.u.constant), Z_UNIVAL(opline->op2.u.constant), diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index d1bafbaa3b..db2066624d 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -2144,7 +2144,7 @@ ZEND_METHOD(reflection_parameter, getDefaultValue) zv_copy = precv->op2.u.constant; zv = &zv_copy; - zval_update_constant(&zv, (void*)0 TSRMLS_CC); + zval_update_constant_ex(&zv, (void*)0, param->fptr->common.scope TSRMLS_CC); RETURN_ZVAL(zv, 1, 1); } /* }}} */ @@ -3961,7 +3961,7 @@ ZEND_METHOD(reflection_property, getDefaultValue) *zv = **zdef; zval_copy_ctor(zv); INIT_PZVAL(zv); - zval_update_constant(&zv, (void*)1 TSRMLS_CC); + zval_update_constant_ex(&zv, (void*)1, ref->ce TSRMLS_CC); RETURN_ZVAL(zv, 1, 1); } } diff --git a/ext/reflection/tests/bug38465.phpt b/ext/reflection/tests/bug38465.phpt new file mode 100644 index 0000000000..fbcf3629a2 --- /dev/null +++ b/ext/reflection/tests/bug38465.phpt @@ -0,0 +1,86 @@ +--TEST-- +Reflection Bug #38465 (ReflectionParameter fails on access to self::) +--SKIPIF-- + +--FILE-- +getProperties() as $property) { + echo $property->getDeclaringClass()->getName(), '::$', $property->getName(), ' = ', $property->getDefaultValue(), "\n"; +} + +foreach ($clazz->getMethods() as $method) { + foreach ($method->getParameters() as $param) { + if ($param->isDefaultValueAvailable()) { + echo $method->getDeclaringClass()->getName(), '::', $method->getName(), '($', $param->getName(), ' = ', $param->getDefaultValue(), ")\n"; + } + } +} + +echo "\nFrom class context:\n"; + +class Test { + function __construct() { + $clazz = new ReflectionClass('Bar'); + foreach ($clazz->getProperties() as $property) { + echo $property->getDeclaringClass()->getName(), '::$', $property->getName(), ' = ', $property->getDefaultValue(), "\n"; + } + + foreach ($clazz->getMethods() as $method) { + foreach ($method->getParameters() as $param) { + if ($param->isDefaultValueAvailable()) { + echo $method->getDeclaringClass()->getName(), '::', $method->getName(), '($', $param->getName(), ' = ', $param->getDefaultValue(), ")\n"; + } + } + } + } +} + +new Test(); + +?> +--EXPECT-- +From global scope: +Bar::$propA = 1 +Bar::$propB = 3 +Bar::$propC = 99 +Bar::y($a = 2) +Bar::y($b = 3) +Bar::y($c = 99) +Foo::x($a = 1) +Foo::x($b = 3) +Foo::x($c = 99) + +From class context: +Bar::$propA = 1 +Bar::$propB = 3 +Bar::$propC = 99 +Bar::y($a = 2) +Bar::y($b = 3) +Bar::y($c = 99) +Foo::x($a = 1) +Foo::x($b = 3) +Foo::x($c = 99) diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 5e28c1b462..0890865f21 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -4216,7 +4216,7 @@ PHP_FUNCTION(constant) return; } - if (!zend_u_get_constant(const_type, const_name, const_name_len, return_value TSRMLS_CC)) { + if (!zend_u_get_constant(const_type, const_name, const_name_len, return_value, NULL TSRMLS_CC)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't find constant %R", const_type, const_name); RETURN_NULL(); }