Skip to content

Commit aad3987

Browse files
committed
Remove bareword fallback for constants
Access to undefined constants will now always result in an Error exception being thrown. This required quite a few test changes, because there were many buggy tests that unintentionally used bareword fallback in combination with error suppression.
1 parent 3d39479 commit aad3987

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+372
-467
lines changed

UPGRADING

+3
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ PHP 8.0 UPGRADE NOTES
2929
longer available. The error_get_last() function may be used instead.
3030
. Removed the ability to define case-insensitive constants. The third
3131
argument to define() may no longer be true.
32+
. Access to undefined constants now always results in an Error exception.
33+
Previously, unqualified constant accesses resulted in a warning and were
34+
interpreted as strings.
3235
. Removed ability to specify an autoloader using an __autoload() function.
3336
spl_autoload_register() should be used instead.
3437
. Removed create_function(). Anonymous functions may be used instead.

Zend/tests/bug37811.phpt

+4-3
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ string(3) "Foo"
2323

2424
Warning: Constants may only evaluate to scalar values, arrays or resources in %sbug37811.php on line %d
2525

26-
Warning: Use of undefined constant Baz - assumed 'Baz' (this will throw an Error in a future version of PHP) in %sbug37811.php on line %d
27-
string(3) "Baz"
28-
===DONE===
26+
Fatal error: Uncaught Error: Undefined constant 'Baz' in %s:%d
27+
Stack trace:
28+
#0 {main}
29+
thrown in %s on line %d

Zend/tests/bug43344_1.phpt

+28-15
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ Bug #43344.1 (Wrong error message for undefined namespace constant)
33
--FILE--
44
<?php
55
namespace Foo;
6+
use Error;
7+
68
function f1($a=bar) {
79
return $a;
810
}
@@ -13,20 +15,31 @@ function f3($a=array(bar=>0)) {
1315
reset($a);
1416
return key($a);
1517
}
16-
echo bar."\n";
17-
echo f1()."\n";
18-
echo f2()."\n";
19-
echo f3()."\n";
20-
?>
21-
--EXPECTF--
22-
Warning: Use of undefined constant bar - assumed 'bar' (this will throw an Error in a future version of PHP) in %sbug43344_1.php on line 13
23-
bar
2418

25-
Warning: Use of undefined constant bar - assumed 'bar' (this will throw an Error in a future version of PHP) in %sbug43344_1.php on line 3
26-
bar
27-
28-
Warning: Use of undefined constant bar - assumed 'bar' (this will throw an Error in a future version of PHP) in %sbug43344_1.php on line 6
29-
bar
19+
try {
20+
echo bar."\n";
21+
} catch (Error $e) {
22+
echo $e->getMessage(), "\n";
23+
}
24+
try {
25+
echo f1()."\n";
26+
} catch (Error $e) {
27+
echo $e->getMessage(), "\n";
28+
}
29+
try {
30+
echo f2()."\n";
31+
} catch (Error $e) {
32+
echo $e->getMessage(), "\n";
33+
}
34+
try {
35+
echo f3()."\n";
36+
} catch (Error $e) {
37+
echo $e->getMessage(), "\n";
38+
}
3039

31-
Warning: Use of undefined constant bar - assumed 'bar' (this will throw an Error in a future version of PHP) in %sbug43344_1.php on line 9
32-
bar
40+
?>
41+
--EXPECT--
42+
Undefined constant 'Foo\bar'
43+
Undefined constant 'Foo\bar'
44+
Undefined constant 'Foo\bar'
45+
Undefined constant 'Foo\bar'

Zend/tests/bug47572.phpt

+4-1
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,7 @@ $foo = new Foo();
1414

1515
?>
1616
--EXPECTF--
17-
Warning: Use of undefined constant FOO - assumed 'FOO' (this will throw an Error in a future version of PHP) in %s on line %d
17+
Fatal error: Uncaught Error: Undefined constant 'FOO' in %s:%d
18+
Stack trace:
19+
#0 {main}
20+
thrown in %s on line %d

Zend/tests/bug69755.phpt

+4-1
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,7 @@ Bug #69755: segfault in ZEND_CONCAT_SPEC_TMPVAR_CONST_HANDLER
55
c . 10;
66
?>
77
--EXPECTF--
8-
Warning: Use of undefined constant c - assumed 'c' (this will throw an Error in a future version of PHP) in %sbug69755.php on line 2
8+
Fatal error: Uncaught Error: Undefined constant 'c' in %s:%d
9+
Stack trace:
10+
#0 {main}
11+
thrown in %s on line %d

Zend/tests/bug69788.phpt

+4-1
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,7 @@ Bug #69788: Malformed script causes Uncaught Error in php-cgi, valgrind SIGILL
55
--EXPECTF--
66
Notice: Array to string conversion in %s on line %d
77

8-
Warning: Use of undefined constant t - assumed 't' (this will throw an Error in a future version of PHP) in %s on line %d
8+
Fatal error: Uncaught Error: Undefined constant 't' in %s:%d
9+
Stack trace:
10+
#0 {main}
11+
thrown in %s on line %d

Zend/tests/bug72944.phpt

+2-3
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,10 @@
22
Bug #72944 (Null pointer deref in zval_delref_p).
33
--FILE--
44
<?php
5+
define('e', 'e');
56
"a"== e & $A = $A? 0 : 0 ?:0;
67
echo "OK\n";
78
?>
89
--EXPECTF--
9-
Warning: Use of undefined constant e - assumed 'e' (this will throw an Error in a future version of PHP) in %sbug72944.php on line 2
10-
11-
Notice: Undefined variable: A in %sbug72944.php on line 2
10+
Notice: Undefined variable: A in %sbug72944.php on line 3
1211
OK

Zend/tests/bug73163.phpt

-22
This file was deleted.

Zend/tests/constants_002.phpt

+7-5
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,17 @@ Defining constants with non-scalar values
44
<?php
55

66
define('foo', new stdClass);
7-
var_dump(foo);
7+
try {
8+
var_dump(foo);
9+
} catch (Error $e) {
10+
echo $e->getMessage(), "\n";
11+
}
812

913
define('foo', fopen(__FILE__, 'r'));
1014
var_dump(foo);
1115

1216
?>
1317
--EXPECTF--
1418
Warning: Constants may only evaluate to scalar values, arrays or resources in %s on line %d
15-
16-
Warning: Use of undefined constant foo - assumed 'foo' (this will throw an Error in a future version of PHP) in %s on line %d
17-
string(%d) "foo"
18-
resource(%d) of type (stream)
19+
Undefined constant 'foo'
20+
resource(5) of type (stream)

Zend/tests/constants_005.phpt

+3-4
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,10 @@
22
Persistent case insensitive and user defined constants
33
--FILE--
44
<?php
5-
var_dump(ZEND_THREAD_safe);
5+
var_dump(defined('ZEND_THREAD_safe'));
66
define("ZEND_THREAD_safe", 123);
77
var_dump(ZEND_THREAD_safe);
88
?>
9-
--EXPECTF--
10-
Warning: Use of undefined constant ZEND_THREAD_safe - assumed 'ZEND_THREAD_safe' (this will throw an Error in a future version of PHP) in %s on line %d
11-
string(16) "ZEND_THREAD_safe"
9+
--EXPECT--
10+
bool(false)
1211
int(123)

Zend/tests/ns_041.phpt

+4-2
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,7 @@ ok
1717
ok
1818
ok
1919

20-
Warning: Use of undefined constant BAR - assumed 'BAR' (this will throw an Error in a future version of PHP) in %sns_041.php on line 9
21-
BAR
20+
Fatal error: Uncaught Error: Undefined constant 'test\ns1\BAR' in %s:%d
21+
Stack trace:
22+
#0 {main}
23+
thrown in %s on line %d

Zend/tests/ns_076.phpt

+20-18
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,28 @@
33
--FILE--
44
<?php
55
namespace foo;
6+
use Error;
67

7-
$a = array(unknown => unknown);
8-
9-
echo unknown;
10-
echo "\n";
11-
var_dump($a);
12-
echo \unknown;
13-
--EXPECTF--
14-
Warning: Use of undefined constant unknown - assumed 'unknown' (this will throw an Error in a future version of PHP) in %sns_076.php on line %d
8+
try {
9+
$a = array(unknown => unknown);
10+
} catch (Error $e) {
11+
echo $e->getMessage(), "\n";
12+
}
1513

16-
Warning: Use of undefined constant unknown - assumed 'unknown' (this will throw an Error in a future version of PHP) in %sns_076.php on line %d
14+
try {
15+
echo unknown;
16+
} catch (Error $e) {
17+
echo $e->getMessage(), "\n";
18+
}
1719

18-
Warning: Use of undefined constant unknown - assumed 'unknown' (this will throw an Error in a future version of PHP) in %sns_076.php on line %d
19-
unknown
20-
array(1) {
21-
["unknown"]=>
22-
%s(7) "unknown"
20+
try {
21+
echo \unknown;
22+
} catch (Error $e) {
23+
echo $e->getMessage(), "\n";
2324
}
2425

25-
Fatal error: Uncaught Error: Undefined constant 'unknown' in %sns_076.php:%d
26-
Stack trace:
27-
#0 {main}
28-
thrown in %sns_076.php on line %d
26+
?>
27+
--EXPECT--
28+
Undefined constant 'foo\unknown'
29+
Undefined constant 'foo\unknown'
30+
Undefined constant 'unknown'

Zend/zend_compile.c

+6-11
Original file line numberDiff line numberDiff line change
@@ -7643,19 +7643,13 @@ void zend_compile_const(znode *result, zend_ast *ast) /* {{{ */
76437643
opline = zend_emit_op_tmp(result, ZEND_FETCH_CONSTANT, NULL, NULL);
76447644
opline->op2_type = IS_CONST;
76457645

7646-
if (is_fully_qualified) {
7646+
if (is_fully_qualified || !FC(current_namespace)) {
76477647
opline->op2.constant = zend_add_const_name_literal(
76487648
resolved_name, 0);
76497649
} else {
7650-
opline->op1.num = IS_CONSTANT_UNQUALIFIED;
7651-
if (FC(current_namespace)) {
7652-
opline->op1.num |= IS_CONSTANT_IN_NAMESPACE;
7653-
opline->op2.constant = zend_add_const_name_literal(
7654-
resolved_name, 1);
7655-
} else {
7656-
opline->op2.constant = zend_add_const_name_literal(
7657-
resolved_name, 0);
7658-
}
7650+
opline->op1.num = IS_CONSTANT_UNQUALIFIED_IN_NAMESPACE;
7651+
opline->op2.constant = zend_add_const_name_literal(
7652+
resolved_name, 1);
76597653
}
76607654
opline->extended_value = zend_alloc_cache_slot();
76617655
}
@@ -7985,7 +7979,8 @@ void zend_compile_const_expr_const(zend_ast **ast_ptr) /* {{{ */
79857979
}
79867980

79877981
zend_ast_destroy(ast);
7988-
*ast_ptr = zend_ast_create_constant(resolved_name, !is_fully_qualified ? IS_CONSTANT_UNQUALIFIED : 0);
7982+
*ast_ptr = zend_ast_create_constant(resolved_name,
7983+
!is_fully_qualified && FC(current_namespace) ? IS_CONSTANT_UNQUALIFIED_IN_NAMESPACE : 0);
79897984
}
79907985
/* }}} */
79917986

Zend/zend_compile.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -917,9 +917,8 @@ void zend_assert_valid_class_name(const zend_string *const_name);
917917

918918
#define ZEND_DIM_IS 1
919919

920-
#define IS_CONSTANT_UNQUALIFIED 0x010
921920
#define IS_CONSTANT_CLASS 0x080 /* __CLASS__ in trait */
922-
#define IS_CONSTANT_IN_NAMESPACE 0x100
921+
#define IS_CONSTANT_UNQUALIFIED_IN_NAMESPACE 0x100
923922

924923
static zend_always_inline int zend_check_arg_send_type(const zend_function *zf, uint32_t arg_num, uint32_t mask)
925924
{

Zend/zend_constants.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@ ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope,
424424
return &c->value;
425425
}
426426

427-
if (!(flags & IS_CONSTANT_UNQUALIFIED)) {
427+
if (!(flags & IS_CONSTANT_UNQUALIFIED_IN_NAMESPACE)) {
428428
return NULL;
429429
}
430430

Zend/zend_execute.c

+3-17
Original file line numberDiff line numberDiff line change
@@ -4153,7 +4153,7 @@ static zend_always_inline int _zend_quick_get_constant(
41534153
zv = zend_hash_find_ex(EG(zend_constants), Z_STR_P(key), 1);
41544154
if (zv) {
41554155
c = (zend_constant*)Z_PTR_P(zv);
4156-
} else if ((flags & (IS_CONSTANT_IN_NAMESPACE|IS_CONSTANT_UNQUALIFIED)) == (IS_CONSTANT_IN_NAMESPACE|IS_CONSTANT_UNQUALIFIED)) {
4156+
} else if (flags & IS_CONSTANT_UNQUALIFIED_IN_NAMESPACE) {
41574157
key++;
41584158
zv = zend_hash_find_ex(EG(zend_constants), Z_STR_P(key), 1);
41594159
if (zv) {
@@ -4163,22 +4163,8 @@ static zend_always_inline int _zend_quick_get_constant(
41634163

41644164
if (!c) {
41654165
if (!check_defined_only) {
4166-
if ((opline->op1.num & IS_CONSTANT_UNQUALIFIED) != 0) {
4167-
char *actual = (char *)zend_memrchr(Z_STRVAL_P(RT_CONSTANT(opline, opline->op2)), '\\', Z_STRLEN_P(RT_CONSTANT(opline, opline->op2)));
4168-
if (!actual) {
4169-
ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_STR_P(RT_CONSTANT(opline, opline->op2)));
4170-
} else {
4171-
actual++;
4172-
ZVAL_STRINGL(EX_VAR(opline->result.var),
4173-
actual, Z_STRLEN_P(RT_CONSTANT(opline, opline->op2)) - (actual - Z_STRVAL_P(RT_CONSTANT(opline, opline->op2))));
4174-
}
4175-
/* non-qualified constant - allow text substitution */
4176-
zend_error(E_WARNING, "Use of undefined constant %s - assumed '%s' (this will throw an Error in a future version of PHP)",
4177-
Z_STRVAL_P(EX_VAR(opline->result.var)), Z_STRVAL_P(EX_VAR(opline->result.var)));
4178-
} else {
4179-
zend_throw_error(NULL, "Undefined constant '%s'", Z_STRVAL_P(RT_CONSTANT(opline, opline->op2)));
4180-
ZVAL_UNDEF(EX_VAR(opline->result.var));
4181-
}
4166+
zend_throw_error(NULL, "Undefined constant '%s'", Z_STRVAL_P(RT_CONSTANT(opline, opline->op2)));
4167+
ZVAL_UNDEF(EX_VAR(opline->result.var));
41824168
}
41834169
return FAILURE;
41844170
}

Zend/zend_execute_API.c

+1-20
Original file line numberDiff line numberDiff line change
@@ -566,29 +566,10 @@ ZEND_API int zend_use_undefined_constant(zend_string *name, zend_ast_attr attr,
566566
} else if ((colon = (char*)zend_memrchr(ZSTR_VAL(name), ':', ZSTR_LEN(name)))) {
567567
zend_throw_error(NULL, "Undefined class constant '%s'", ZSTR_VAL(name));
568568
return FAILURE;
569-
} else if ((attr & IS_CONSTANT_UNQUALIFIED) == 0) {
569+
} else {
570570
zend_throw_error(NULL, "Undefined constant '%s'", ZSTR_VAL(name));
571571
return FAILURE;
572-
} else {
573-
char *actual = ZSTR_VAL(name);
574-
size_t actual_len = ZSTR_LEN(name);
575-
char *slash = (char *) zend_memrchr(actual, '\\', actual_len);
576-
577-
if (slash) {
578-
actual = slash + 1;
579-
actual_len -= (actual - ZSTR_VAL(name));
580-
}
581-
582-
zend_error(E_WARNING, "Use of undefined constant %s - assumed '%s' (this will throw an Error in a future version of PHP)", actual, actual);
583-
if (EG(exception)) {
584-
return FAILURE;
585-
} else {
586-
zend_string *result_str = zend_string_init(actual, actual_len, 0);
587-
zval_ptr_dtor_nogc(result);
588-
ZVAL_NEW_STR(result, result_str);
589-
}
590572
}
591-
return SUCCESS;
592573
}
593574
/* }}} */
594575

ext/opcache/Optimizer/compact_literals.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
171171
LITERAL_INFO(opline->op1.constant, LITERAL_CONST, 1);
172172
break;
173173
case ZEND_FETCH_CONSTANT:
174-
if ((opline->op1.num & (IS_CONSTANT_IN_NAMESPACE|IS_CONSTANT_UNQUALIFIED)) == (IS_CONSTANT_IN_NAMESPACE|IS_CONSTANT_UNQUALIFIED)) {
174+
if (opline->op1.num & IS_CONSTANT_UNQUALIFIED_IN_NAMESPACE) {
175175
LITERAL_INFO(opline->op2.constant, LITERAL_CONST, 3);
176176
} else {
177177
LITERAL_INFO(opline->op2.constant, LITERAL_CONST, 2);

ext/opcache/Optimizer/zend_dump.c

+2-5
Original file line numberDiff line numberDiff line change
@@ -127,11 +127,8 @@ static void zend_dump_unused_op(const zend_op *opline, znode_op op, uint32_t fla
127127
} else if (ZEND_VM_OP_CONSTRUCTOR == (flags & ZEND_VM_OP_MASK)) {
128128
fprintf(stderr, " CONSTRUCTOR");
129129
} else if (ZEND_VM_OP_CONST_FETCH == (flags & ZEND_VM_EXT_MASK)) {
130-
if (op.num & IS_CONSTANT_UNQUALIFIED) {
131-
fprintf(stderr, " (unqualified)");
132-
}
133-
if (op.num & IS_CONSTANT_IN_NAMESPACE) {
134-
fprintf(stderr, " (in-namespace)");
130+
if (op.num & IS_CONSTANT_UNQUALIFIED_IN_NAMESPACE) {
131+
fprintf(stderr, " (unqualified-in-namespace)");
135132
}
136133
}
137134
}

ext/opcache/tests/bug66251.phpt

+5-2
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,8 @@ const A="hello";
1313
function getA() {return A;}
1414
?>
1515
--EXPECTF--
16-
Warning: Use of undefined constant A - assumed 'A' (this will throw an Error in a future version of PHP) in %sbug66251.php on line 4
17-
A=A
16+
Fatal error: Uncaught Error: Undefined constant 'A' in %s:%d
17+
Stack trace:
18+
#0 %s(%d): getA()
19+
#1 {main}
20+
thrown in %s on line %d

0 commit comments

Comments
 (0)