Skip to content

Commit 2b1b384

Browse files
TysonAndrenikic
authored andcommitted
Fix inconsistency in true/false/null constant resolution when opcache is not used (#7441)
Strangely, uses of eval and 'php -a' (or loading a file without opcache after a namespaced constant was declared) will not treat non-FQ true/false/null as magic keywords, while compiled php required from a file would do that. This may confuse people learning the language, and result in code loaded with eval() behaving differently from the same snippet in a file loaded by require. ``` Interactive shell php > define('foo\true', 'test'); php > namespace foo { var_dump(true); } string(4) "test" ``` This will make the same session instead properly emit `bool(true);` like it already would if running those statements in files when opcache was used. (cherry picked from commit 4c48fd2)
1 parent 86379b6 commit 2b1b384

File tree

2 files changed

+39
-18
lines changed

2 files changed

+39
-18
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
--TEST--
2+
eval() constant resolution
3+
--FILE--
4+
<?php
5+
namespace foo {
6+
define('foo\true', 'test');
7+
echo "In eval\n";
8+
eval('namespace foo { var_dump(true); var_dump(TrUe); var_dump(namespace\true); var_dump(\true); }');
9+
echo "Outside eval\n";
10+
var_dump(true); var_dump(TrUe); var_dump(namespace\true); var_dump(\true);
11+
}
12+
?>
13+
--EXPECT--
14+
In eval
15+
bool(true)
16+
bool(true)
17+
string(4) "test"
18+
bool(true)
19+
Outside eval
20+
bool(true)
21+
bool(true)
22+
string(4) "test"
23+
bool(true)

Zend/zend_compile.c

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1396,28 +1396,26 @@ static bool can_ct_eval_const(zend_constant *c) {
13961396

13971397
static bool zend_try_ct_eval_const(zval *zv, zend_string *name, bool is_fully_qualified) /* {{{ */
13981398
{
1399-
zend_constant *c = zend_hash_find_ptr(EG(zend_constants), name);
1399+
/* Substitute true, false and null (including unqualified usage in namespaces)
1400+
* before looking up the possibly namespaced name. */
1401+
const char *lookup_name = ZSTR_VAL(name);
1402+
size_t lookup_len = ZSTR_LEN(name);
1403+
1404+
if (!is_fully_qualified) {
1405+
zend_get_unqualified_name(name, &lookup_name, &lookup_len);
1406+
}
1407+
1408+
zend_constant *c;
1409+
if ((c = zend_get_special_const(lookup_name, lookup_len))) {
1410+
ZVAL_COPY_VALUE(zv, &c->value);
1411+
return 1;
1412+
}
1413+
c = zend_hash_find_ptr(EG(zend_constants), name);
14001414
if (c && can_ct_eval_const(c)) {
14011415
ZVAL_COPY_OR_DUP(zv, &c->value);
14021416
return 1;
14031417
}
1404-
1405-
{
1406-
/* Substitute true, false and null (including unqualified usage in namespaces) */
1407-
const char *lookup_name = ZSTR_VAL(name);
1408-
size_t lookup_len = ZSTR_LEN(name);
1409-
1410-
if (!is_fully_qualified) {
1411-
zend_get_unqualified_name(name, &lookup_name, &lookup_len);
1412-
}
1413-
1414-
if ((c = zend_get_special_const(lookup_name, lookup_len))) {
1415-
ZVAL_COPY_VALUE(zv, &c->value);
1416-
return 1;
1417-
}
1418-
1419-
return 0;
1420-
}
1418+
return 0;
14211419
}
14221420
/* }}} */
14231421

0 commit comments

Comments
 (0)