]> granicus.if.org Git - php/commitdiff
Fixed some class constant issues related to bug #41633
authorDmitry Stogov <dmitry@php.net>
Wed, 13 Jun 2007 14:50:33 +0000 (14:50 +0000)
committerDmitry Stogov <dmitry@php.net>
Wed, 13 Jun 2007 14:50:33 +0000 (14:50 +0000)
Zend/tests/bug41633_1.phpt [new file with mode: 0755]
Zend/tests/bug41633_2.phpt [new file with mode: 0755]
Zend/zend_execute_API.c
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

diff --git a/Zend/tests/bug41633_1.phpt b/Zend/tests/bug41633_1.phpt
new file mode 100755 (executable)
index 0000000..1c1d552
--- /dev/null
@@ -0,0 +1,12 @@
+--TEST--
+Bug #41633.1 (self:: doesn't work for constants)
+--FILE--
+<?php
+class Foo {
+       const A = self::B;
+       const B = "ok";
+}
+echo Foo::A."\n";
+?>
+--EXPECT--
+ok
diff --git a/Zend/tests/bug41633_2.phpt b/Zend/tests/bug41633_2.phpt
new file mode 100755 (executable)
index 0000000..3deb451
--- /dev/null
@@ -0,0 +1,11 @@
+--TEST--
+Bug #41633.2 (Undefined class constants must not be substituted by strings)
+--FILE--
+<?php
+class Foo {
+       const A = self::B;
+}
+echo Foo::A."\n";
+?>
+--EXPECTF--
+Fatal error: Undefined class constant 'self::B' in %sbug41633_2.php on line 5
index 6009fea4f366001f3bc2745c8900e00018971e6a..2041a3d42fc188f567b0bb7eeed98351f7ff7e2b 100644 (file)
@@ -474,6 +474,7 @@ ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *sco
        zval *p = *pp;
        zend_bool inline_change = (zend_bool) (zend_uintptr_t) arg;
        zval const_value;
+       zstr colon;
 
        if (Z_TYPE_P(p) == IS_CONSTANT) {
                int refcount;
@@ -486,6 +487,10 @@ ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *sco
                is_ref = p->is_ref;
 
                if (!zend_u_get_constant(ZEND_STR_TYPE, Z_UNIVAL_P(p), Z_UNILEN_P(p), &const_value, scope TSRMLS_CC)) {
+                       if ((UG(unicode) && (colon.u = u_memchr(Z_USTRVAL_P(p), ':', Z_USTRLEN_P(p))) && colon.u[1] == ':') ||
+                           (!UG(unicode) && (colon.s = memchr(Z_STRVAL_P(p), ':', Z_STRLEN_P(p))) && colon.s[1] == ':')) {
+                               zend_error(E_ERROR, "Undefined class constant '%v'", Z_UNIVAL_P(p));
+                       }
                        zend_error(E_NOTICE, "Use of undefined constant %v - assumed '%v'",
                                Z_UNIVAL_P(p),
                                Z_UNIVAL_P(p));
@@ -525,6 +530,10 @@ ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *sco
                                continue;
                        }
                        if (!zend_u_get_constant(ZEND_STR_TYPE, str_index, str_index_len-1, &const_value, scope TSRMLS_CC)) {
+                               if ((UG(unicode) && (colon.u = u_memchr(str_index.u, ':', str_index_len-1)) && colon.u[1] == ':') ||
+                                   (!UG(unicode) && (colon.s = memchr(str_index.s, ':', str_index_len-1)) && colon.s[1] == ':')) {
+                                       zend_error(E_ERROR, "Undefined class constant '%v'", str_index);
+                               }
                                zend_error(E_NOTICE, "Use of undefined constant %v - assumed '%v'",     str_index, str_index);
                                zend_hash_move_forward(Z_ARRVAL_P(p));
                                continue;
index 9dd76f3a4bb9373616722d8c8ed04556f69d12cd..0917ef655b241d16541beddffb919ab629fbebff 100644 (file)
@@ -2671,7 +2671,11 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, CONST|UNUSED, CONST)
        ce = EX_T(opline->op1.u.var).class_entry;
 
        if (zend_u_hash_find(&ce->constants_table, Z_TYPE(opline->op2.u.constant), Z_UNIVAL(opline->op2.u.constant), Z_UNILEN(opline->op2.u.constant)+1, (void **) &value) == SUCCESS) {
+               zend_class_entry *old_scope = EG(scope);
+
+               EG(scope) = ce;
                zval_update_constant(value, (void *) 1 TSRMLS_CC);
+               EG(scope) = old_scope;
                EX_T(opline->result.u.var).tmp_var = **value;
                zval_copy_ctor(&EX_T(opline->result.u.var).tmp_var);
        } else {
index 3c75a345185b7c3ea339c75b0f0774b7d9109755..3004be7a5bad458d06bcf7e00daf8ac191860b35 100644 (file)
@@ -2753,7 +2753,11 @@ static int ZEND_FETCH_CONSTANT_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS
        ce = EX_T(opline->op1.u.var).class_entry;
 
        if (zend_u_hash_find(&ce->constants_table, Z_TYPE(opline->op2.u.constant), Z_UNIVAL(opline->op2.u.constant), Z_UNILEN(opline->op2.u.constant)+1, (void **) &value) == SUCCESS) {
+               zend_class_entry *old_scope = EG(scope);
+
+               EG(scope) = ce;
                zval_update_constant(value, (void *) 1 TSRMLS_CC);
+               EG(scope) = old_scope;
                EX_T(opline->result.u.var).tmp_var = **value;
                zval_copy_ctor(&EX_T(opline->result.u.var).tmp_var);
        } else {
@@ -16048,7 +16052,11 @@ static int ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG
        ce = EX_T(opline->op1.u.var).class_entry;
 
        if (zend_u_hash_find(&ce->constants_table, Z_TYPE(opline->op2.u.constant), Z_UNIVAL(opline->op2.u.constant), Z_UNILEN(opline->op2.u.constant)+1, (void **) &value) == SUCCESS) {
+               zend_class_entry *old_scope = EG(scope);
+
+               EG(scope) = ce;
                zval_update_constant(value, (void *) 1 TSRMLS_CC);
+               EG(scope) = old_scope;
                EX_T(opline->result.u.var).tmp_var = **value;
                zval_copy_ctor(&EX_T(opline->result.u.var).tmp_var);
        } else {