]> granicus.if.org Git - php/commitdiff
- MFH: Fix #38465 (ReflectionParameter fails if default value is an access to self::
authorJohannes Schlüter <johannes@php.net>
Wed, 18 Oct 2006 16:35:15 +0000 (16:35 +0000)
committerJohannes Schlüter <johannes@php.net>
Wed, 18 Oct 2006 16:35:15 +0000 (16:35 +0000)
NEWS
Zend/zend_constants.c
Zend/zend_constants.h
Zend/zend_execute.h
Zend/zend_execute_API.c
ext/reflection/php_reflection.c
ext/reflection/tests/bug38465.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index d5f0414aafcb849b4477563c10413552ce2957cc..d0499ad06a83308880f49ca5ab338372575ae22d 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -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)
index ec3e1e587a6f9d866c115b66279ff57ba532da8c..08de962cd68e276a06d15a33cdda80900508cb95 100644 (file)
@@ -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)
 {
index a0cc2b1bb584029f25240e76f40434d9b2c5c456..eead3caac7d7f422032f2d2f17190202be2c68b3 100644 (file)
@@ -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);
index 11b92bd68032bf504483b5a06c86d23b4aae6bfb..eb350e7f3e77c64a46e20ff1f243f72b6a818837 100644 (file)
@@ -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)
index 524b78735f36aa16a7e25444b8a5764196b1db4c..3098bf4850746f1951f7e24f4d19fe370af7fe18 100644 (file)
@@ -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)
 {
index 22b134bba8a918a777f5daa0fd0563b247d920af..cf88d3f8606a2d0837e403baf0477295040f239b 100644 (file)
@@ -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 (file)
index 0000000..4947180
--- /dev/null
@@ -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)