Skip to content

Commit 1391a0f

Browse files
committed
Fixed bug #75893
It is not sufficient to just add the additional types for aliased variables at the end of type inference, because types of derived variables may depend on them. Make sure the additional types are always added whenever the type of an aliased variable is updated.
1 parent d9e7116 commit 1391a0f

File tree

3 files changed

+42
-13
lines changed

3 files changed

+42
-13
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ PHP NEWS
2121

2222
- Opcache:
2323
. Fixed bug #75729 (opcache segfault when installing Bitrix). (Nikita)
24+
. Fixed bug #75893 (file_get_contents $http_response_header variable bugged
25+
with opcache). (Nikita)
2426

2527
- Standard:
2628
. Fixed bug #75916 (DNS_CAA record results contain garbage). (Mike,

ext/opcache/Optimizer/zend_inference.c

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1734,6 +1734,16 @@ static int zend_infer_ranges(const zend_op_array *op_array, zend_ssa *ssa) /* {{
17341734
}
17351735
/* }}} */
17361736

1737+
static uint32_t get_ssa_alias_types(zend_ssa_alias_kind alias) {
1738+
if (alias == PHP_ERRORMSG_ALIAS) {
1739+
return MAY_BE_STRING | MAY_BE_RC1 | MAY_BE_RCN;
1740+
} else if (alias == HTTP_RESPONSE_HEADER_ALIAS) {
1741+
return MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_LONG | MAY_BE_ARRAY_OF_STRING | MAY_BE_RC1 | MAY_BE_RCN;
1742+
} else {
1743+
return MAY_BE_UNDEF | MAY_BE_RC1 | MAY_BE_RCN | MAY_BE_REF | MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF;
1744+
}
1745+
}
1746+
17371747
#define UPDATE_SSA_TYPE(_type, _var) \
17381748
do { \
17391749
uint32_t __type = (_type); \
@@ -1742,14 +1752,18 @@ static int zend_infer_ranges(const zend_op_array *op_array, zend_ssa *ssa) /* {{
17421752
__type |= MAY_BE_RC1 | MAY_BE_RCN | MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF; \
17431753
} \
17441754
if (__var >= 0) { \
1745-
if (ssa_vars[__var].var < op_array->last_var) { \
1755+
zend_ssa_var *__ssa_var = &ssa_vars[__var]; \
1756+
if (__ssa_var->var < op_array->last_var) { \
17461757
if (__type & (MAY_BE_REF|MAY_BE_RCN)) { \
17471758
__type |= MAY_BE_RC1 | MAY_BE_RCN; \
17481759
} \
17491760
if ((__type & MAY_BE_RC1) && (__type & MAY_BE_STRING)) {\
17501761
/* TODO: support for array keys and ($str . "")*/ \
17511762
__type |= MAY_BE_RCN; \
17521763
} \
1764+
if (__ssa_var->alias) { \
1765+
__type |= get_ssa_alias_types(__ssa_var->alias); \
1766+
} \
17531767
} \
17541768
if (ssa_var_info[__var].type != __type) { \
17551769
if (ssa_var_info[__var].type & ~__type) { \
@@ -3880,18 +3894,6 @@ static int zend_infer_types(const zend_op_array *op_array, const zend_script *sc
38803894
/* Narrowing integer initialization to doubles */
38813895
zend_type_narrowing(op_array, script, ssa);
38823896

3883-
for (j = 0; j < ssa_vars_count; j++) {
3884-
if (ssa->vars[j].alias) {
3885-
if (ssa->vars[j].alias == PHP_ERRORMSG_ALIAS) {
3886-
ssa_var_info[j].type |= MAY_BE_STRING | MAY_BE_RC1 | MAY_BE_RCN;
3887-
} else if (ssa->vars[j].alias == HTTP_RESPONSE_HEADER_ALIAS) {
3888-
ssa_var_info[j].type |= MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_LONG | MAY_BE_ARRAY_OF_STRING | MAY_BE_RC1 | MAY_BE_RCN;
3889-
} else {
3890-
ssa_var_info[j].type = MAY_BE_UNDEF | MAY_BE_RC1 | MAY_BE_RCN | MAY_BE_REF | MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF;
3891-
}
3892-
}
3893-
}
3894-
38953897
if (ZEND_FUNC_INFO(op_array)) {
38963898
zend_func_return_info(op_array, script, 1, 0, &ZEND_FUNC_INFO(op_array)->return_info);
38973899
}
@@ -3919,6 +3921,9 @@ int zend_ssa_inference(zend_arena **arena, const zend_op_array *op_array, const
39193921
for (i = 0; i < op_array->last_var; i++) {
39203922
ssa_var_info[i].type = MAY_BE_UNDEF;
39213923
ssa_var_info[i].has_range = 0;
3924+
if (ssa->vars[i].alias) {
3925+
ssa_var_info[i].type |= get_ssa_alias_types(ssa->vars[i].alias);
3926+
}
39223927
}
39233928
}
39243929
for (i = op_array->last_var; i < ssa->vars_count; i++) {

ext/opcache/tests/bug75893.phpt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
--TEST--
2+
Bug #75893: file_get_contents $http_response_header variable bugged with opcache
3+
--INI--
4+
opcache.enable_cli=1
5+
track_errors=1
6+
--FILE--
7+
<?php
8+
9+
function test() {
10+
echo $undef;
11+
$foo = $php_errormsg;
12+
var_dump($foo[0]);
13+
}
14+
15+
test();
16+
17+
?>
18+
--EXPECTF--
19+
Deprecated: Directive 'track_errors' is deprecated in Unknown on line 0
20+
21+
Notice: Undefined variable: undef in %s on line %d
22+
string(1) "U"

0 commit comments

Comments
 (0)