diff options
author | Johannes Schlüter <johannes@php.net> | 2006-10-18 16:35:15 +0000 |
---|---|---|
committer | Johannes Schlüter <johannes@php.net> | 2006-10-18 16:35:15 +0000 |
commit | dcf249004c3eea72b3405b3829b7f912fb4c6492 (patch) | |
tree | a48d29b75f4fe6c5ad1d8ed2a530bd869b16ce3e | |
parent | b99ba323d56d16c598a37d8ae89b8472e974c42b (diff) | |
download | php-git-dcf249004c3eea72b3405b3829b7f912fb4c6492.tar.gz |
- MFH: Fix #38465 (ReflectionParameter fails if default value is an access to self::
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | Zend/zend_constants.c | 18 | ||||
-rw-r--r-- | Zend/zend_constants.h | 1 | ||||
-rw-r--r-- | Zend/zend_execute.h | 1 | ||||
-rw-r--r-- | Zend/zend_execute_API.c | 10 | ||||
-rw-r--r-- | ext/reflection/php_reflection.c | 2 | ||||
-rw-r--r-- | ext/reflection/tests/bug38465.phpt | 66 |
7 files changed, 90 insertions, 10 deletions
@@ -19,6 +19,8 @@ PHP NEWS - Fixed bug #38934 (move_uploaded_file() cannot read uploaded file outside of open_basedir). (Ilia) - Fixed bug #38649 (uninit'd optional arg in stream_socket_sendto()). (Sara) +- Fixed bug #38465 (ReflectionParameter fails if default value is an access to + self::). (Johannes) - Fixed bug #38198 (possible crash when COM reports an exception). (Ilia) - Fixed bug #37262 (var_export() does not escape \0 character). (Ilia) - Fixed bug #36515 (Unlinking buckets from non-existant brigades). (Sara) diff --git a/Zend/zend_constants.c b/Zend/zend_constants.c index ec3e1e587a..08de962cd6 100644 --- a/Zend/zend_constants.c +++ b/Zend/zend_constants.c @@ -213,7 +213,7 @@ ZEND_API void zend_register_string_constant(char *name, uint name_len, char *str } -ZEND_API int zend_get_constant(char *name, uint name_len, zval *result TSRMLS_DC) +ZEND_API int zend_get_constant_ex(char *name, uint name_len, zval *result, zend_class_entry *scope TSRMLS_DC) { zend_constant *c; int retval = 1; @@ -222,17 +222,19 @@ ZEND_API int zend_get_constant(char *name, uint name_len, zval *result TSRMLS_DC if ((colon = memchr(name, ':', name_len)) && colon[1] == ':') { /* class constant */ - zend_class_entry **ce = NULL, *scope; + zend_class_entry **ce = NULL; int class_name_len = colon-name; int const_name_len = name_len - class_name_len - 2; char *constant_name = colon+2; zval **ret_constant; char *class_name; - 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); + } } class_name = estrndup(name, class_name_len); @@ -300,6 +302,10 @@ ZEND_API int zend_get_constant(char *name, uint name_len, zval *result TSRMLS_DC return retval; } +ZEND_API int zend_get_constant(char *name, uint name_len, zval *result TSRMLS_DC) +{ + zend_get_constant_ex(name, name_len, result, NULL TSRMLS_CC); +} ZEND_API int zend_register_constant(zend_constant *c TSRMLS_DC) { diff --git a/Zend/zend_constants.h b/Zend/zend_constants.h index a0cc2b1bb5..eead3caac7 100644 --- a/Zend/zend_constants.h +++ b/Zend/zend_constants.h @@ -56,6 +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_get_constant_ex(char *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 11b92bd680..eb350e7f3e 100644 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@ -134,6 +134,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 524b78735f..3098bf4850 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -448,7 +448,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; @@ -464,7 +464,7 @@ ZEND_API int zval_update_constant(zval **pp, void *arg TSRMLS_DC) refcount = p->refcount; is_ref = p->is_ref; - if (!zend_get_constant(p->value.str.val, p->value.str.len, &const_value TSRMLS_CC)) { + if (!zend_get_constant_ex(p->value.str.val, p->value.str.len, &const_value, scope TSRMLS_CC)) { zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", p->value.str.val, p->value.str.val); @@ -503,7 +503,7 @@ ZEND_API int zval_update_constant(zval **pp, void *arg TSRMLS_DC) zend_hash_move_forward(Z_ARRVAL_P(p)); continue; } - if (!zend_get_constant(str_index, str_index_len-1, &const_value TSRMLS_CC)) { + if (!zend_get_constant_ex(str_index, str_index_len-1, &const_value, scope TSRMLS_CC)) { zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", str_index, str_index); zend_hash_move_forward(Z_ARRVAL_P(p)); continue; @@ -552,6 +552,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/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 22b134bba8..cf88d3f860 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -2132,7 +2132,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); } /* }}} */ diff --git a/ext/reflection/tests/bug38465.phpt b/ext/reflection/tests/bug38465.phpt new file mode 100644 index 0000000000..4947180e92 --- /dev/null +++ b/ext/reflection/tests/bug38465.phpt @@ -0,0 +1,66 @@ +--TEST-- +Reflection Bug #38465 (ReflectionParameter fails on access to self::) +--SKIPIF-- +<?php extension_loaded('reflection') or die('skip'); ?> +--FILE-- +<?php +class Baz { + const B = 3; +} + +class Foo { + const X = 1; + public function x($a = self::X, $b = Baz::B, $c = 99) {} +} + +class Bar extends Foo { + const Y = 2; + public function y($a = self::Y, $b = Baz::B, $c = 99) {} +} + + +echo "From global scope:\n"; + +$clazz = new ReflectionClass('Bar'); +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->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::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::y($a = 2) +Bar::y($b = 3) +Bar::y($c = 99) +Foo::x($a = 1) +Foo::x($b = 3) +Foo::x($c = 99) |