--- /dev/null
+--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
--- /dev/null
+--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
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;
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));
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;
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 {
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 {
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 {