Skip to content

Commit

Permalink
Fixed bug #75893
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
nikic committed Feb 5, 2018
1 parent d9e7116 commit 1391a0f
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 13 deletions.
2 changes: 2 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ PHP NEWS

- Opcache:
. Fixed bug #75729 (opcache segfault when installing Bitrix). (Nikita)
. Fixed bug #75893 (file_get_contents $http_response_header variable bugged
with opcache). (Nikita)

- Standard:
. Fixed bug #75916 (DNS_CAA record results contain garbage). (Mike,
Expand Down
31 changes: 18 additions & 13 deletions ext/opcache/Optimizer/zend_inference.c
Original file line number Diff line number Diff line change
Expand Up @@ -1734,6 +1734,16 @@ static int zend_infer_ranges(const zend_op_array *op_array, zend_ssa *ssa) /* {{
}
/* }}} */

static uint32_t get_ssa_alias_types(zend_ssa_alias_kind alias) {
if (alias == PHP_ERRORMSG_ALIAS) {
return MAY_BE_STRING | MAY_BE_RC1 | MAY_BE_RCN;
} else if (alias == HTTP_RESPONSE_HEADER_ALIAS) {
return MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_LONG | MAY_BE_ARRAY_OF_STRING | MAY_BE_RC1 | MAY_BE_RCN;
} else {
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;
}
}

#define UPDATE_SSA_TYPE(_type, _var) \
do { \
uint32_t __type = (_type); \
Expand All @@ -1742,14 +1752,18 @@ static int zend_infer_ranges(const zend_op_array *op_array, zend_ssa *ssa) /* {{
__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; \
} \
if (__var >= 0) { \
if (ssa_vars[__var].var < op_array->last_var) { \
zend_ssa_var *__ssa_var = &ssa_vars[__var]; \
if (__ssa_var->var < op_array->last_var) { \
if (__type & (MAY_BE_REF|MAY_BE_RCN)) { \
__type |= MAY_BE_RC1 | MAY_BE_RCN; \
} \
if ((__type & MAY_BE_RC1) && (__type & MAY_BE_STRING)) {\
/* TODO: support for array keys and ($str . "")*/ \
__type |= MAY_BE_RCN; \
} \
if (__ssa_var->alias) { \
__type |= get_ssa_alias_types(__ssa_var->alias); \
} \
} \
if (ssa_var_info[__var].type != __type) { \
if (ssa_var_info[__var].type & ~__type) { \
Expand Down Expand Up @@ -3880,18 +3894,6 @@ static int zend_infer_types(const zend_op_array *op_array, const zend_script *sc
/* Narrowing integer initialization to doubles */
zend_type_narrowing(op_array, script, ssa);

for (j = 0; j < ssa_vars_count; j++) {
if (ssa->vars[j].alias) {
if (ssa->vars[j].alias == PHP_ERRORMSG_ALIAS) {
ssa_var_info[j].type |= MAY_BE_STRING | MAY_BE_RC1 | MAY_BE_RCN;
} else if (ssa->vars[j].alias == HTTP_RESPONSE_HEADER_ALIAS) {
ssa_var_info[j].type |= MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_LONG | MAY_BE_ARRAY_OF_STRING | MAY_BE_RC1 | MAY_BE_RCN;
} else {
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;
}
}
}

if (ZEND_FUNC_INFO(op_array)) {
zend_func_return_info(op_array, script, 1, 0, &ZEND_FUNC_INFO(op_array)->return_info);
}
Expand Down Expand Up @@ -3919,6 +3921,9 @@ int zend_ssa_inference(zend_arena **arena, const zend_op_array *op_array, const
for (i = 0; i < op_array->last_var; i++) {
ssa_var_info[i].type = MAY_BE_UNDEF;
ssa_var_info[i].has_range = 0;
if (ssa->vars[i].alias) {
ssa_var_info[i].type |= get_ssa_alias_types(ssa->vars[i].alias);
}
}
}
for (i = op_array->last_var; i < ssa->vars_count; i++) {
Expand Down
22 changes: 22 additions & 0 deletions ext/opcache/tests/bug75893.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
--TEST--
Bug #75893: file_get_contents $http_response_header variable bugged with opcache
--INI--
opcache.enable_cli=1
track_errors=1
--FILE--
<?php

function test() {
echo $undef;
$foo = $php_errormsg;
var_dump($foo[0]);
}

test();

?>
--EXPECTF--
Deprecated: Directive 'track_errors' is deprecated in Unknown on line 0

Notice: Undefined variable: undef in %s on line %d
string(1) "U"

0 comments on commit 1391a0f

Please sign in to comment.