Merge branch 'PHP-7.1'

This commit is contained in:
Nikita Popov 2017-06-23 17:33:36 +02:00
commit 272a9f29f5
2 changed files with 44 additions and 13 deletions

View File

@ -1746,8 +1746,11 @@ static int zend_infer_ranges(const zend_op_array *op_array, zend_ssa *ssa) /* {{
} \
} \
if (ssa_var_info[__var].type != __type) { \
check_type_narrowing(op_array, ssa, worklist, \
__var, ssa_var_info[__var].type, __type); \
if (ssa_var_info[__var].type & ~__type) { \
handle_type_narrowing(op_array, ssa, worklist, \
__var, ssa_var_info[__var].type, __type); \
return FAILURE; \
} \
ssa_var_info[__var].type = __type; \
add_usages(op_array, ssa, worklist, __var); \
} \
@ -1884,15 +1887,17 @@ static void reset_dependent_vars(const zend_op_array *op_array, zend_ssa *ssa, z
#endif
}
static void check_type_narrowing(const zend_op_array *op_array, zend_ssa *ssa, zend_bitset worklist, int var, uint32_t old_type, uint32_t new_type)
static void handle_type_narrowing(const zend_op_array *op_array, zend_ssa *ssa, zend_bitset worklist, int var, uint32_t old_type, uint32_t new_type)
{
/* if new_type set resets some bits from old_type set
* We have completely recalculate types of some dependent SSA variables
* (this may occurs mainly because of incremental inter-precudure
* type inference)
*/
if (old_type & ~new_type) {
ZEND_ASSERT(0); /* Currently this should never happen */
if (1) {
/* Right now, this is always a bug */
zend_error(E_WARNING, "Narrowing occurred during type inference. Please file a bug report on bugs.php.net");
} else {
/* if new_type set resets some bits from old_type set
* We have completely recalculate types of some dependent SSA variables
* (this may occurs mainly because of incremental inter-precudure
* type inference)
*/
reset_dependent_vars(op_array, ssa, worklist, var);
}
}
@ -2120,7 +2125,7 @@ static uint32_t zend_fetch_arg_info(const zend_script *script, zend_arg_info *ar
return tmp;
}
static void zend_update_type_info(const zend_op_array *op_array,
static int zend_update_type_info(const zend_op_array *op_array,
zend_ssa *ssa,
const zend_script *script,
zend_bitset worklist,
@ -3100,7 +3105,7 @@ static void zend_update_type_info(const zend_op_array *op_array,
opline->opcode == ZEND_FETCH_OBJ_RW ||
opline->opcode == ZEND_FETCH_OBJ_FUNC_ARG) {
if (opline->opcode != ZEND_FETCH_DIM_FUNC_ARG) {
if (t1 & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_NULL)) {
if (t1 & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_FALSE)) {
tmp &= ~(MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_FALSE);
tmp |= MAY_BE_OBJECT | MAY_BE_RC1 | MAY_BE_RCN;
}
@ -3229,6 +3234,8 @@ unknown_opcode:
}
break;
}
return SUCCESS;
}
static uint32_t get_class_entry_rank(zend_class_entry *ce) {
@ -3339,7 +3346,9 @@ int zend_infer_types_ex(const zend_op_array *op_array, const zend_script *script
}
} else if (ssa_vars[j].definition >= 0) {
i = ssa_vars[j].definition;
zend_update_type_info(op_array, ssa, script, worklist, i);
if (zend_update_type_info(op_array, ssa, script, worklist, i) == FAILURE) {
return FAILURE;
}
}
} WHILE_WORKLIST_END();
return SUCCESS;

View File

@ -0,0 +1,22 @@
--TEST--
Bug #74623: Infinite loop in type inference when using HTMLPurifier
--FILE--
<?php
function crash($arr) {
$current_item = false;
foreach($arr as $item) {
if($item->name === 'string') {
$current_item = $item;
} else {
$current_item->a[] = '';
}
}
}
?>
===DONE===
--EXPECT--
===DONE===