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

index 68a52e37607ceb2a51618734c690d3e2f77d4a2b..3c90193a050496f707a4a1a7b1adeac4f13ea5a7 100644 (file)
@@ -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 {
index 089ef6d93b9368be24373553b74e5b415f966384..eac88543c05e2ffafd1f6f1395759f99cf1e963e 100644 (file)
@@ -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)
index 319a3b9bf2694d639b5b3ee33be61bf78ec759a4..79e5e30be6d941ec561303601aa27093ff91a14e 100644 (file)
@@ -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);
index 787467b7614875214768e5a67fe3414e8a4c0ff2..ecf4228f33506dc67af5c56aa090d21fa616a298 100644 (file)
@@ -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)
index dc53e2ac475503f8f39e811d7edeb8aa25ea7965..7f8eb7b326f2575bbfd8d66111d2162082d7c6b9 100644 (file)
@@ -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)
 {
index b9ce080a891b7fb7983338a9c7a02a1bec974e35..fc398d7b695dc1293a7269e9d0d20745d1bdb380 100644 (file)
@@ -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),
index b39cfbafb8c6e335239e7cf315c18f8b1ef5999f..d31a89159b20ad99772bf7193829ca2913d62c0f 100644 (file)
@@ -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),
index d1bafbaa3b94fd5e9990ea60de2a8e880ae6f180..db2066624de69223fb8d1b2c8297e4b13239cc18 100644 (file)
@@ -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 (file)
index 0000000..fbcf362
--- /dev/null
@@ -0,0 +1,86 @@
+--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;
+    private $propA = self::X;
+    private $propB = Baz::B;
+    private $propC = 99;
+    public function x($a = self::X, $b = Baz::B, $c = 99) {}
+}
+
+class Bar extends Foo {
+    const Y = 2;
+    private $propA = self::X;
+    private $propB = Baz::B;
+    private $propC = 99;
+    public function y($a = self::Y, $b = Baz::B, $c = 99) {}
+}
+
+
+echo "From global scope:\n";
+
+$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";
+        }
+    }
+}
+
+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)
index 5e28c1b46229d439404cafd11bfd4a77f7dc140f..0890865f2181ae8b03d92e030c5e8b4f4e626eba 100644 (file)
@@ -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();
        }