Skip to content

Commit 31f6f15

Browse files
committed
Fixed bug #43344 (Wrong error message for undefined namespace constant)
1 parent ee1e57e commit 31f6f15

21 files changed

+332
-25
lines changed

Zend/tests/bug43343.phpt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
--TEST--
2+
Bug #43343 (Variable class name)
3+
--FILE--
4+
<?php
5+
namespace Foo;
6+
class Bar { }
7+
$foo = 'bar';
8+
var_dump(new namespace::$foo);
9+
?>
10+
--EXPECTF--
11+
Fatal error: Cannot use 'namespace' as a class name in %sbug43343.php on line 5

Zend/tests/bug43344_1.phpt

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
--TEST--
2+
Bug #43344.1 (Wrong error message for undefined namespace constant)
3+
--FILE--
4+
<?php
5+
namespace Foo;
6+
function f1($a=bar) {
7+
return $a;
8+
}
9+
function f2($a=array(bar)) {
10+
return $a[0];
11+
}
12+
function f3($a=array(bar=>0)) {
13+
reset($a);
14+
return key($a);
15+
}
16+
echo bar."\n";
17+
echo f1()."\n";
18+
echo f2()."\n";
19+
echo f3()."\n";
20+
?>
21+
--EXPECTF--
22+
Notice: Use of undefined constant bar - assumed 'bar' in %sbug43344_1.php on line 13
23+
bar
24+
25+
Notice: Use of undefined constant bar - assumed 'bar' in %sbug43344_1.php on line 3
26+
bar
27+
28+
Notice: Use of undefined constant bar - assumed 'bar' in %sbug43344_1.php on line 6
29+
bar
30+
31+
Notice: Use of undefined constant bar - assumed 'bar' in %sbug43344_1.php on line 9
32+
bar

Zend/tests/bug43344_10.phpt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
--TEST--
2+
Bug #43344.10 (Wrong error message for undefined namespace constant)
3+
--FILE--
4+
<?php
5+
echo namespace::bar."\n";
6+
?>
7+
--EXPECTF--
8+
Fatal error: Undefined constant 'bar' in %sbug43344_10.php on line %d

Zend/tests/bug43344_11.phpt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
--TEST--
2+
Bug #43344.11 (Wrong error message for undefined namespace constant)
3+
--FILE--
4+
<?php
5+
function f($a=namespace::bar) {
6+
return $a;
7+
}
8+
echo f()."\n";
9+
?>
10+
--EXPECTF--
11+
Fatal error: Undefined constant 'bar' in %sbug43344_11.php on line %d

Zend/tests/bug43344_12.phpt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
--TEST--
2+
Bug #43344.12 (Wrong error message for undefined namespace constant)
3+
--FILE--
4+
<?php
5+
function f($a=array(namespace::bar)) {
6+
return $a[0];
7+
}
8+
echo f()."\n";
9+
?>
10+
--EXPECTF--
11+
Fatal error: Undefined constant 'bar' in %sbug43344_12.php on line %d

Zend/tests/bug43344_13.phpt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
--TEST--
2+
Bug #43344.13 (Wrong error message for undefined namespace constant)
3+
--FILE--
4+
<?php
5+
function f($a=array(namespace::bar=>0)) {
6+
reset($a);
7+
return key($a);
8+
}
9+
echo f()."\n";
10+
?>
11+
--EXPECTF--
12+
Fatal error: Undefined constant 'bar' in %sbug43344_13.php on line %d

Zend/tests/bug43344_2.phpt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
--TEST--
2+
Bug #43344.2 (Wrong error message for undefined namespace constant)
3+
--FILE--
4+
<?php
5+
namespace Foo;
6+
echo Foo::bar."\n";
7+
?>
8+
--EXPECTF--
9+
Fatal error: Class 'Foo::Foo' not found in %sbug43344_2.php on line %d

Zend/tests/bug43344_3.phpt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
--TEST--
2+
Bug #43344.3 (Wrong error message for undefined namespace constant)
3+
--FILE--
4+
<?php
5+
namespace Foo;
6+
function f($a=Foo::bar) {
7+
return $a;
8+
}
9+
echo f()."\n";
10+
?>
11+
--EXPECTF--
12+
Fatal error: Class 'Foo::Foo' not found in %sbug43344_3.php on line %d

Zend/tests/bug43344_4.phpt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
--TEST--
2+
Bug #43344.4 (Wrong error message for undefined namespace constant)
3+
--FILE--
4+
<?php
5+
namespace Foo;
6+
function f($a=array(Foo::bar)) {
7+
return $a[0];
8+
}
9+
echo f()."\n";
10+
?>
11+
--EXPECTF--
12+
Fatal error: Class 'Foo::Foo' not found in %sbug43344_4.php on line %d

Zend/tests/bug43344_5.phpt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
--TEST--
2+
Bug #43344.5 (Wrong error message for undefined namespace constant)
3+
--FILE--
4+
<?php
5+
namespace Foo;
6+
function f($a=array(Foo::bar=>0)) {
7+
reset($a);
8+
return key($a);
9+
}
10+
echo f()."\n";
11+
?>
12+
--EXPECTF--
13+
Fatal error: Class 'Foo::Foo' not found in %sbug43344_5.php on line %d

Zend/tests/bug43344_6.phpt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
--TEST--
2+
Bug #43344.6 (Wrong error message for undefined namespace constant)
3+
--FILE--
4+
<?php
5+
namespace Foo;
6+
echo namespace::bar."\n";
7+
?>
8+
--EXPECTF--
9+
Fatal error: Undefined constant 'Foo::bar' in %sbug43344_6.php on line %d

Zend/tests/bug43344_7.phpt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
--TEST--
2+
Bug #43344.7 (Wrong error message for undefined namespace constant)
3+
--FILE--
4+
<?php
5+
namespace Foo;
6+
function f($a=namespace::bar) {
7+
return $a;
8+
}
9+
echo f()."\n";
10+
?>
11+
--EXPECTF--
12+
Fatal error: Undefined constant 'Foo::bar' in %sbug43344_7.php on line %d

Zend/tests/bug43344_8.phpt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
--TEST--
2+
Bug #43344.8 (Wrong error message for undefined namespace constant)
3+
--FILE--
4+
<?php
5+
namespace Foo;
6+
function f($a=array(namespace::bar)) {
7+
return $a[0];
8+
}
9+
echo f()."\n";
10+
?>
11+
--EXPECTF--
12+
Fatal error: Undefined constant 'Foo::bar' in %sbug43344_8.php on line %d

Zend/tests/bug43344_9.phpt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
--TEST--
2+
Bug #43344.9 (Wrong error message for undefined namespace constant)
3+
--FILE--
4+
<?php
5+
namespace Foo;
6+
function f($a=array(namespace::bar=>0)) {
7+
reset($a);
8+
return key($a);
9+
}
10+
echo f()."\n";
11+
?>
12+
--EXPECTF--
13+
Fatal error: Undefined constant 'Foo::bar' in %sbug43344_9.php on line %d

Zend/tests/lsb_018.phpt

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,3 +93,41 @@ object(Baz)#%d (1) {
9393
int(2)
9494
}
9595
===DONE===
96+
--UEXPECTF--
97+
object(Foo)#%d (1) {
98+
[u"instanceId":u"Singleton":private]=>
99+
int(0)
100+
}
101+
object(Bar)#%d (1) {
102+
[u"instanceId":u"Singleton":private]=>
103+
int(1)
104+
}
105+
object(Baz)#%d (1) {
106+
[u"instanceId":u"Singleton":private]=>
107+
int(2)
108+
}
109+
object(Foo)#%d (1) {
110+
[u"instanceId":u"Singleton":private]=>
111+
int(0)
112+
}
113+
object(Bar)#%d (1) {
114+
[u"instanceId":u"Singleton":private]=>
115+
int(1)
116+
}
117+
object(Baz)#%d (1) {
118+
[u"instanceId":u"Singleton":private]=>
119+
int(2)
120+
}
121+
object(Foo)#%d (1) {
122+
[u"instanceId":u"Singleton":private]=>
123+
int(0)
124+
}
125+
object(Bar)#%d (1) {
126+
[u"instanceId":u"Singleton":private]=>
127+
int(1)
128+
}
129+
object(Baz)#%d (1) {
130+
[u"instanceId":u"Singleton":private]=>
131+
int(2)
132+
}
133+
===DONE===

Zend/tests/ns_057.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
057: Usage of 'namespace' in compound names (inside namespase)
33
--FILE--
44
<?php
5-
namespace test::ns1;
5+
namespace Test::ns1;
66

77
const C = "const ok\n";
88

Zend/zend_compile.c

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1395,6 +1395,7 @@ void zend_do_receive_arg(zend_uchar op, znode *var, znode *offset, znode *initia
13951395
zend_arg_info *cur_arg_info;
13961396

13971397
if (class_type->op_type == IS_CONST &&
1398+
Z_TYPE(class_type->u.constant) == ZEND_STR_TYPE &&
13981399
Z_UNILEN(class_type->u.constant) == 0) {
13991400
/* Usage of namespace as class name not in namespace */
14001401
zval_dtor(&class_type->u.constant);
@@ -1758,6 +1759,7 @@ void zend_do_fetch_class(znode *result, znode *class_name TSRMLS_DC) /* {{{ */
17581759
zend_op *opline;
17591760

17601761
if (class_name->op_type == IS_CONST &&
1762+
Z_TYPE(class_name->u.constant) == ZEND_STR_TYPE &&
17611763
Z_UNILEN(class_name->u.constant) == 0) {
17621764
/* Usage of namespace as class name not in namespace */
17631765
zval_dtor(&class_name->u.constant);
@@ -1835,9 +1837,19 @@ int zend_do_begin_class_member_function_call(znode *class_name, znode *method_na
18351837
ulong fetch_type = 0;
18361838

18371839
if (class_name->op_type == IS_CONST &&
1840+
Z_TYPE(class_name->u.constant) == ZEND_STR_TYPE &&
18381841
Z_UNILEN(class_name->u.constant) == 0) {
18391842
/* namespace::func() not in namespace */
18401843
zval_dtor(&class_name->u.constant);
1844+
if (CG(current_namespace)) {
1845+
znode tmp;
1846+
1847+
tmp.op_type = IS_CONST;
1848+
tmp.u.constant = *CG(current_namespace);
1849+
zval_copy_ctor(&tmp.u.constant);
1850+
zend_do_build_namespace_name(&tmp, &tmp, method_name TSRMLS_CC);
1851+
*method_name = tmp;
1852+
}
18411853
return zend_do_begin_function_call(method_name, 0 TSRMLS_CC);
18421854
}
18431855

@@ -3868,6 +3880,17 @@ void zend_do_fetch_constant(znode *result, znode *constant_container, znode *con
38683880
ulong fetch_type = 0;
38693881
znode tmp;
38703882

3883+
if (constant_container &&
3884+
constant_container->op_type == IS_CONST &&
3885+
Z_TYPE(constant_container->u.constant) == ZEND_STR_TYPE &&
3886+
Z_UNILEN(constant_container->u.constant) == 0) {
3887+
/* namespace::const */
3888+
zval_dtor(&constant_container->u.constant);
3889+
check_namespace = 1;
3890+
constant_container = NULL;
3891+
fetch_type = ZEND_FETCH_CLASS_RT_NS_CHECK | IS_CONSTANT_RT_NS_CHECK;;
3892+
}
3893+
38713894
switch (mode) {
38723895
case ZEND_CT:
38733896
if (constant_container) {
@@ -3881,7 +3904,7 @@ void zend_do_fetch_constant(znode *result, znode *constant_container, znode *con
38813904
zend_do_fetch_class_name(NULL, constant_container, constant_name TSRMLS_CC);
38823905
*result = *constant_container;
38833906
result->u.constant.type = IS_CONSTANT | fetch_type;
3884-
} else if (!zend_constant_ct_subst(result, &constant_name->u.constant TSRMLS_CC)) {
3907+
} else if (fetch_type || !zend_constant_ct_subst(result, &constant_name->u.constant TSRMLS_CC)) {
38853908
if (check_namespace && CG(current_namespace)) {
38863909
/* We assume we use constant from the current namespace
38873910
if it is not prefixed. */
@@ -3890,22 +3913,13 @@ void zend_do_fetch_constant(znode *result, znode *constant_container, znode *con
38903913
zval_copy_ctor(&tmp.u.constant);
38913914
zend_do_build_namespace_name(&tmp, &tmp, constant_name TSRMLS_CC);
38923915
*constant_name = tmp;
3893-
fetch_type = IS_CONSTANT_RT_NS_CHECK;
3916+
fetch_type |= IS_CONSTANT_RT_NS_CHECK;
38943917
}
38953918
*result = *constant_name;
38963919
result->u.constant.type = IS_CONSTANT | fetch_type;
38973920
}
38983921
break;
38993922
case ZEND_RT:
3900-
if (constant_container &&
3901-
constant_container->op_type == IS_CONST &&
3902-
Z_UNILEN(constant_container->u.constant) == 0) {
3903-
/* Usage of namespace as class name not in namespace */
3904-
zval_dtor(&constant_container->u.constant);
3905-
constant_container = NULL;
3906-
check_namespace = 0;
3907-
}
3908-
39093923
if (constant_container ||
39103924
!zend_constant_ct_subst(result, &constant_name->u.constant TSRMLS_CC)) {
39113925
zend_op *opline;
@@ -3925,11 +3939,11 @@ void zend_do_fetch_constant(znode *result, znode *constant_container, znode *con
39253939
tmp.u.constant = *CG(current_namespace);
39263940
zval_copy_ctor(&tmp.u.constant);
39273941
constant_container = &tmp;
3928-
fetch_type = IS_CONSTANT_RT_NS_CHECK;
3942+
fetch_type |= IS_CONSTANT_RT_NS_CHECK;
39293943
}
39303944
opline = get_next_op(CG(active_op_array) TSRMLS_CC);
39313945
opline->opcode = ZEND_FETCH_CONSTANT;
3932-
opline->extended_value = fetch_type & ~ZEND_FETCH_CLASS_RT_NS_NAME;
3946+
opline->extended_value = fetch_type & ~ZEND_FETCH_CLASS_RT_NS_NAME;
39333947
opline->result.op_type = IS_TMP_VAR;
39343948
opline->result.u.var = get_temporary_variable(CG(active_op_array));
39353949
if (constant_container) {
@@ -5181,6 +5195,19 @@ void zend_do_build_namespace_name(znode *result, znode *prefix, znode *name TSRM
51815195

51825196
if (prefix) {
51835197
*result = *prefix;
5198+
if (Z_TYPE(result->u.constant) == ZEND_STR_TYPE &&
5199+
Z_UNILEN(result->u.constant) == 0) {
5200+
/* namespace:: */
5201+
if (CG(current_namespace)) {
5202+
znode tmp;
5203+
5204+
zval_dtor(&result->u.constant);
5205+
tmp.op_type = IS_CONST;
5206+
tmp.u.constant = *CG(current_namespace);
5207+
zval_copy_ctor(&tmp.u.constant);
5208+
zend_do_build_namespace_name(result, NULL, &tmp TSRMLS_CC);
5209+
}
5210+
}
51845211
} else {
51855212
result->op_type = IS_CONST;
51865213
Z_TYPE(result->u.constant) = ZEND_STR_TYPE;

0 commit comments

Comments
 (0)