Merge branch 'PHP-7.0'

This commit is contained in:
Nikita Popov 2016-02-24 17:44:33 +01:00
commit 55c0de8f95
5 changed files with 74 additions and 62 deletions

View File

@ -3049,7 +3049,7 @@ ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|THIS|CV, CONST|T
} }
} }
if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
GET_OP1_UNDEF_CV(object, BP_VAR_R); object = GET_OP1_UNDEF_CV(object, BP_VAR_R);
if (UNEXPECTED(EG(exception) != NULL)) { if (UNEXPECTED(EG(exception) != NULL)) {
FREE_OP2(); FREE_OP2();
HANDLE_EXCEPTION(); HANDLE_EXCEPTION();

View File

@ -5884,7 +5884,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_CO
} }
} }
if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
GET_OP1_UNDEF_CV(object, BP_VAR_R); object = GET_OP1_UNDEF_CV(object, BP_VAR_R);
if (UNEXPECTED(EG(exception) != NULL)) { if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION(); HANDLE_EXCEPTION();
@ -9586,7 +9586,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_CV
} }
} }
if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
GET_OP1_UNDEF_CV(object, BP_VAR_R); object = GET_OP1_UNDEF_CV(object, BP_VAR_R);
if (UNEXPECTED(EG(exception) != NULL)) { if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION(); HANDLE_EXCEPTION();
@ -11386,7 +11386,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_TM
} }
} }
if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
GET_OP1_UNDEF_CV(object, BP_VAR_R); object = GET_OP1_UNDEF_CV(object, BP_VAR_R);
if (UNEXPECTED(EG(exception) != NULL)) { if (UNEXPECTED(EG(exception) != NULL)) {
zval_ptr_dtor_nogc(free_op2); zval_ptr_dtor_nogc(free_op2);
HANDLE_EXCEPTION(); HANDLE_EXCEPTION();
@ -27693,7 +27693,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C
} }
} }
if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
GET_OP1_UNDEF_CV(object, BP_VAR_R); object = GET_OP1_UNDEF_CV(object, BP_VAR_R);
if (UNEXPECTED(EG(exception) != NULL)) { if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION(); HANDLE_EXCEPTION();
@ -30990,7 +30990,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C
} }
} }
if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
GET_OP1_UNDEF_CV(object, BP_VAR_R); object = GET_OP1_UNDEF_CV(object, BP_VAR_R);
if (UNEXPECTED(EG(exception) != NULL)) { if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION(); HANDLE_EXCEPTION();
@ -33231,7 +33231,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_T
} }
} }
if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
GET_OP1_UNDEF_CV(object, BP_VAR_R); object = GET_OP1_UNDEF_CV(object, BP_VAR_R);
if (UNEXPECTED(EG(exception) != NULL)) { if (UNEXPECTED(EG(exception) != NULL)) {
zval_ptr_dtor_nogc(free_op2); zval_ptr_dtor_nogc(free_op2);
HANDLE_EXCEPTION(); HANDLE_EXCEPTION();
@ -38565,7 +38565,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CONST
} }
} }
if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
GET_OP1_UNDEF_CV(object, BP_VAR_R); object = GET_OP1_UNDEF_CV(object, BP_VAR_R);
if (UNEXPECTED(EG(exception) != NULL)) { if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION(); HANDLE_EXCEPTION();
@ -44935,7 +44935,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HA
} }
} }
if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
GET_OP1_UNDEF_CV(object, BP_VAR_R); object = GET_OP1_UNDEF_CV(object, BP_VAR_R);
if (UNEXPECTED(EG(exception) != NULL)) { if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION(); HANDLE_EXCEPTION();
@ -48357,7 +48357,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVA
} }
} }
if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
GET_OP1_UNDEF_CV(object, BP_VAR_R); object = GET_OP1_UNDEF_CV(object, BP_VAR_R);
if (UNEXPECTED(EG(exception) != NULL)) { if (UNEXPECTED(EG(exception) != NULL)) {
zval_ptr_dtor_nogc(free_op2); zval_ptr_dtor_nogc(free_op2);
HANDLE_EXCEPTION(); HANDLE_EXCEPTION();
@ -50519,7 +50519,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C
} }
} }
if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
GET_OP1_UNDEF_CV(object, BP_VAR_R); object = GET_OP1_UNDEF_CV(object, BP_VAR_R);
if (UNEXPECTED(EG(exception) != NULL)) { if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION(); HANDLE_EXCEPTION();
@ -52753,7 +52753,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C
} }
} }
if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
GET_OP1_UNDEF_CV(object, BP_VAR_R); object = GET_OP1_UNDEF_CV(object, BP_VAR_R);
if (UNEXPECTED(EG(exception) != NULL)) { if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION(); HANDLE_EXCEPTION();
@ -53891,7 +53891,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_T
} }
} }
if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
GET_OP1_UNDEF_CV(object, BP_VAR_R); object = GET_OP1_UNDEF_CV(object, BP_VAR_R);
if (UNEXPECTED(EG(exception) != NULL)) { if (UNEXPECTED(EG(exception) != NULL)) {
zval_ptr_dtor_nogc(free_op2); zval_ptr_dtor_nogc(free_op2);
HANDLE_EXCEPTION(); HANDLE_EXCEPTION();

View File

@ -275,7 +275,7 @@ static zval *spl_array_get_dimension_ptr(int check_inherited, zval *object, zval
return &EG(uninitialized_zval); return &EG(uninitialized_zval);
} }
if ((type == BP_VAR_W || type == BP_VAR_RW) && (ht->u.v.nApplyCount > 0)) { if ((type == BP_VAR_W || type == BP_VAR_RW) && intern->nApplyCount > 0) {
zend_error(E_WARNING, "Modification of ArrayObject during sorting is prohibited"); zend_error(E_WARNING, "Modification of ArrayObject during sorting is prohibited");
return &EG(error_zval); return &EG(error_zval);
} }
@ -434,16 +434,8 @@ static void spl_array_write_dimension_ex(int check_inherited, zval *object, zval
return; return;
} }
if (!offset) { if (intern->nApplyCount > 0) {
ht = spl_array_get_hash_table(intern); zend_error(E_WARNING, "Modification of ArrayObject during sorting is prohibited");
if (ht->u.v.nApplyCount > 0) {
zend_error(E_WARNING, "Modification of ArrayObject during sorting is prohibited");
return;
}
if (Z_REFCOUNTED_P(value)) {
Z_ADDREF_P(value);
}
zend_hash_next_index_insert(ht, value);
return; return;
} }
@ -451,14 +443,16 @@ static void spl_array_write_dimension_ex(int check_inherited, zval *object, zval
Z_ADDREF_P(value); Z_ADDREF_P(value);
} }
if (!offset) {
ht = spl_array_get_hash_table(intern);
zend_hash_next_index_insert(ht, value);
return;
}
try_again: try_again:
switch (Z_TYPE_P(offset)) { switch (Z_TYPE_P(offset)) {
case IS_STRING: case IS_STRING:
ht = spl_array_get_hash_table(intern); ht = spl_array_get_hash_table(intern);
if (ht->u.v.nApplyCount > 0) {
zend_error(E_WARNING, "Modification of ArrayObject during sorting is prohibited");
return;
}
zend_symtable_update_ind(ht, Z_STR_P(offset), value); zend_symtable_update_ind(ht, Z_STR_P(offset), value);
return; return;
case IS_DOUBLE: case IS_DOUBLE:
@ -477,18 +471,10 @@ try_again:
index = Z_LVAL_P(offset); index = Z_LVAL_P(offset);
num_index: num_index:
ht = spl_array_get_hash_table(intern); ht = spl_array_get_hash_table(intern);
if (ht->u.v.nApplyCount > 0) {
zend_error(E_WARNING, "Modification of ArrayObject during sorting is prohibited");
return;
}
zend_hash_index_update(ht, index, value); zend_hash_index_update(ht, index, value);
return; return;
case IS_NULL: case IS_NULL:
ht = spl_array_get_hash_table(intern); ht = spl_array_get_hash_table(intern);
if (ht->u.v.nApplyCount > 0) {
zend_error(E_WARNING, "Modification of ArrayObject during sorting is prohibited");
return;
}
zend_hash_next_index_insert(ht, value); zend_hash_next_index_insert(ht, value);
return; return;
case IS_REFERENCE: case IS_REFERENCE:
@ -496,6 +482,7 @@ num_index:
goto try_again; goto try_again;
default: default:
zend_error(E_WARNING, "Illegal offset type"); zend_error(E_WARNING, "Illegal offset type");
zval_ptr_dtor(value);
return; return;
} }
} /* }}} */ } /* }}} */
@ -518,14 +505,15 @@ static void spl_array_unset_dimension_ex(int check_inherited, zval *object, zval
return; return;
} }
if (intern->nApplyCount > 0) {
zend_error(E_WARNING, "Modification of ArrayObject during sorting is prohibited");
return;
}
try_again: try_again:
switch (Z_TYPE_P(offset)) { switch (Z_TYPE_P(offset)) {
case IS_STRING: case IS_STRING:
ht = spl_array_get_hash_table(intern); ht = spl_array_get_hash_table(intern);
if (ht->u.v.nApplyCount > 0) {
zend_error(E_WARNING, "Modification of ArrayObject during sorting is prohibited");
return;
}
if (ht == &EG(symbol_table)) { if (ht == &EG(symbol_table)) {
if (zend_delete_global_variable(Z_STR_P(offset))) { if (zend_delete_global_variable(Z_STR_P(offset))) {
zend_error(E_NOTICE,"Undefined index: %s", Z_STRVAL_P(offset)); zend_error(E_NOTICE,"Undefined index: %s", Z_STRVAL_P(offset));
@ -571,10 +559,6 @@ try_again:
index = Z_LVAL_P(offset); index = Z_LVAL_P(offset);
num_index: num_index:
ht = spl_array_get_hash_table(intern); ht = spl_array_get_hash_table(intern);
if (ht->u.v.nApplyCount > 0) {
zend_error(E_WARNING, "Modification of ArrayObject during sorting is prohibited");
return;
}
if (zend_hash_index_del(ht, index) == FAILURE) { if (zend_hash_index_del(ht, index) == FAILURE) {
zend_error(E_NOTICE,"Undefined offset: %pd", index); zend_error(E_NOTICE,"Undefined offset: %pd", index);
} }
@ -798,11 +782,6 @@ SPL_METHOD(Array, getArrayCopy)
static HashTable *spl_array_get_properties(zval *object) /* {{{ */ static HashTable *spl_array_get_properties(zval *object) /* {{{ */
{ {
spl_array_object *intern = Z_SPLARRAY_P(object); spl_array_object *intern = Z_SPLARRAY_P(object);
HashTable *result;
if (intern->nApplyCount > 1) {
php_error_docref(NULL, E_ERROR, "Nesting level too deep - recursive dependency?");
}
if (intern->ar_flags & SPL_ARRAY_STD_PROP_LIST) { if (intern->ar_flags & SPL_ARRAY_STD_PROP_LIST) {
if (!intern->std.properties) { if (!intern->std.properties) {
@ -811,10 +790,7 @@ static HashTable *spl_array_get_properties(zval *object) /* {{{ */
return intern->std.properties; return intern->std.properties;
} }
intern->nApplyCount++; return spl_array_get_hash_table(intern);
result = spl_array_get_hash_table(intern);
intern->nApplyCount--;
return result;
} /* }}} */ } /* }}} */
static HashTable* spl_array_get_debug_info(zval *obj, int *is_temp) /* {{{ */ static HashTable* spl_array_get_debug_info(zval *obj, int *is_temp) /* {{{ */
@ -1447,9 +1423,9 @@ static void spl_array_method(INTERNAL_FUNCTION_PARAMETERS, char *fname, int fnam
ZVAL_ARR(Z_REFVAL(params[0]), aht); ZVAL_ARR(Z_REFVAL(params[0]), aht);
if (!use_arg) { if (!use_arg) {
aht->u.v.nApplyCount++; intern->nApplyCount++;
call_user_function_ex(EG(function_table), NULL, &function_name, return_value, 1, params, 1, NULL); call_user_function_ex(EG(function_table), NULL, &function_name, return_value, 1, params, 1, NULL);
aht->u.v.nApplyCount--; intern->nApplyCount--;
} else if (use_arg == SPL_ARRAY_METHOD_MAY_USER_ARG) { } else if (use_arg == SPL_ARRAY_METHOD_MAY_USER_ARG) {
if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "|z", &arg) == FAILURE) { if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "|z", &arg) == FAILURE) {
zend_throw_exception(spl_ce_BadMethodCallException, "Function expects one argument at most", 0); zend_throw_exception(spl_ce_BadMethodCallException, "Function expects one argument at most", 0);
@ -1458,18 +1434,18 @@ static void spl_array_method(INTERNAL_FUNCTION_PARAMETERS, char *fname, int fnam
if (arg) { if (arg) {
ZVAL_COPY_VALUE(&params[1], arg); ZVAL_COPY_VALUE(&params[1], arg);
} }
aht->u.v.nApplyCount++; intern->nApplyCount++;
call_user_function_ex(EG(function_table), NULL, &function_name, return_value, arg ? 2 : 1, params, 1, NULL); call_user_function_ex(EG(function_table), NULL, &function_name, return_value, arg ? 2 : 1, params, 1, NULL);
aht->u.v.nApplyCount--; intern->nApplyCount--;
} else { } else {
if (ZEND_NUM_ARGS() != 1 || zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "z", &arg) == FAILURE) { if (ZEND_NUM_ARGS() != 1 || zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "z", &arg) == FAILURE) {
zend_throw_exception(spl_ce_BadMethodCallException, "Function expects exactly one argument", 0); zend_throw_exception(spl_ce_BadMethodCallException, "Function expects exactly one argument", 0);
goto exit; goto exit;
} }
ZVAL_COPY_VALUE(&params[1], arg); ZVAL_COPY_VALUE(&params[1], arg);
aht->u.v.nApplyCount++; intern->nApplyCount++;
call_user_function_ex(EG(function_table), NULL, &function_name, return_value, 2, params, 1, NULL); call_user_function_ex(EG(function_table), NULL, &function_name, return_value, 2, params, 1, NULL);
aht->u.v.nApplyCount--; intern->nApplyCount--;
} }
exit: exit:
@ -1735,7 +1711,6 @@ SPL_METHOD(Array, unserialize)
const unsigned char *p, *s; const unsigned char *p, *s;
php_unserialize_data_t var_hash; php_unserialize_data_t var_hash;
zval *members, *zflags; zval *members, *zflags;
HashTable *aht;
zend_long flags; zend_long flags;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &buf, &buf_len) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &buf, &buf_len) == FAILURE) {
@ -1746,8 +1721,7 @@ SPL_METHOD(Array, unserialize)
return; return;
} }
aht = spl_array_get_hash_table(intern); if (intern->nApplyCount > 0) {
if (aht->u.v.nApplyCount > 0) {
zend_error(E_WARNING, "Modification of ArrayObject during sorting is prohibited"); zend_error(E_WARNING, "Modification of ArrayObject during sorting is prohibited");
return; return;
} }

View File

@ -0,0 +1,27 @@
--TEST--
Dumping an ArrayObject while it is being sorted
--FILE--
<?php
$ao = new ArrayObject([1, 2, 3]);
$i = 0;
$ao->uasort(function($a, $b) use ($ao, &$i) {
if ($i++ == 0) {
var_dump($ao);
}
return $a <=> $b;
});
?>
--EXPECT--
object(ArrayObject)#1 (1) {
["storage":"ArrayObject":private]=>
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
}

View File

@ -0,0 +1,11 @@
--TEST--
Assignments to illegal ArrayObject offsets shouldn't leak
--FILE--
<?php
$ao = new ArrayObject([1, 2, 3]);
$ao[[]] = new stdClass;
?>
--EXPECTF--
Warning: Illegal offset type in %s on line %d