From: Nikita Popov Date: Thu, 26 Sep 2019 14:05:24 +0000 (+0200) Subject: Convert "cannot add element" warning to exception X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f2b09969db675adf7fa767378deb894c9bf029e0;p=php Convert "cannot add element" warning to exception --- diff --git a/UPGRADING b/UPGRADING index 62e2d9d625..805e23163f 100644 --- a/UPGRADING +++ b/UPGRADING @@ -91,6 +91,10 @@ PHP 8.0 UPGRADE NOTES the value into an object (if it was null, false or an empty string) or ignored the write altogether (in all other cases). RFC: Part of https://wiki.php.net/rfc/engine_warnings + . Attempting to append an element to an array for which the PHP_INT_MAX key + is already used will now result in an Error exception. Previously this was + a warning. + RFC: Part of https://wiki.php.net/rfc/engine_warnings - COM: . Removed the ability to import case-insensitive constants from type diff --git a/Zend/tests/array_literal_next_element_error.phpt b/Zend/tests/array_literal_next_element_error.phpt index 8b4af3cadd..23dec5e22c 100644 --- a/Zend/tests/array_literal_next_element_error.phpt +++ b/Zend/tests/array_literal_next_element_error.phpt @@ -4,22 +4,21 @@ Next free element may overflow in array literals 42, new stdClass]; -var_dump($array); - -const FOO = [PHP_INT_MAX => 42, "foo"]; -var_dump(FOO); - -?> ---EXPECTF-- -Warning: Cannot add element to the array as the next element is already occupied in %s on line %d -array(1) { - [%d]=> - int(42) +try { + $array = [$i => 42, new stdClass]; + var_dump($array); +} catch (Error $e) { + echo $e->getMessage(), "\n"; } -Warning: Cannot add element to the array as the next element is already occupied in %s on line %d -array(1) { - [%d]=> - int(42) +function test($x = [PHP_INT_MAX => 42, "foo"]) {} +try { + test(); +} catch (Error $e) { + echo $e->getMessage(), "\n"; } + +?> +--EXPECT-- +Cannot add element to the array as the next element is already occupied +Cannot add element to the array as the next element is already occupied diff --git a/Zend/tests/array_unpack/already_occupied.phpt b/Zend/tests/array_unpack/already_occupied.phpt index 27a18b6ced..b2febe0021 100644 --- a/Zend/tests/array_unpack/already_occupied.phpt +++ b/Zend/tests/array_unpack/already_occupied.phpt @@ -6,36 +6,28 @@ Appending to an array via unpack may fail 0, ...$arr]); - -var_dump([PHP_INT_MAX-1 => 0, ...[1, 2, 3]]); - -const ARR = [1, 2, 3]; -const ARR2 = [PHP_INT_MAX-1 => 0, ...ARR]; -var_dump(ARR2); - -?> ---EXPECTF-- -Warning: Cannot add element to the array as the next element is already occupied in %s on line %d -array(2) { - [9223372036854775806]=> - int(0) - [9223372036854775807]=> - int(1) +try { + var_dump([PHP_INT_MAX-1 => 0, ...$arr]); +} catch (Error $e) { + echo $e->getMessage(), "\n"; } -Warning: Cannot add element to the array as the next element is already occupied in %s on line %d -array(2) { - [9223372036854775806]=> - int(0) - [9223372036854775807]=> - int(1) +try { + var_dump([PHP_INT_MAX-1 => 0, ...[1, 2, 3]]); +} catch (Error $e) { + echo $e->getMessage(), "\n"; } -Warning: Cannot add element to the array as the next element is already occupied in %s on line %d -array(2) { - [9223372036854775806]=> - int(0) - [9223372036854775807]=> - int(1) +const ARR = [1, 2, 3]; +function test($x = [PHP_INT_MAX-1 => 0, ...ARR]) {} +try { + test(); +} catch (Error $e) { + echo $e->getMessage(), "\n"; } + +?> +--EXPECT-- +Cannot add element to the array as the next element is already occupied +Cannot add element to the array as the next element is already occupied +Cannot add element to the array as the next element is already occupied diff --git a/Zend/tests/assign_dim_obj_null_return.phpt b/Zend/tests/assign_dim_obj_null_return.phpt index c5131cc2d1..e09c753d4a 100644 --- a/Zend/tests/assign_dim_obj_null_return.phpt +++ b/Zend/tests/assign_dim_obj_null_return.phpt @@ -7,12 +7,22 @@ function test() { $array = [PHP_INT_MAX => 42]; $true = true; - var_dump($array[] = 123); + try { + var_dump($array[] = 123); + } catch (Error $e) { + echo $e->getMessage(), "\n"; + } + var_dump($array[[]] = 123); var_dump($array[new stdClass] = 123); var_dump($true[123] = 456); - var_dump($array[] += 123); + try { + var_dump($array[] += 123); + } catch (Error $e) { + echo $e->getMessage(), "\n"; + } + var_dump($array[[]] += 123); var_dump($array[new stdClass] += 123); var_dump($true[123] += 456); @@ -33,8 +43,7 @@ test(); ?> --EXPECTF-- -Warning: Cannot add element to the array as the next element is already occupied in %s on line %d -NULL +Cannot add element to the array as the next element is already occupied Warning: Illegal offset type in %s on line %d NULL @@ -44,9 +53,7 @@ NULL Warning: Cannot use a scalar value as an array in %s on line %d NULL - -Warning: Cannot add element to the array as the next element is already occupied in %s on line %d -NULL +Cannot add element to the array as the next element is already occupied Warning: Illegal offset type in %s on line %d NULL diff --git a/Zend/tests/assign_ref_error_var_handling.phpt b/Zend/tests/assign_ref_error_var_handling.phpt index bcbce9401d..2a66b68cc5 100644 --- a/Zend/tests/assign_ref_error_var_handling.phpt +++ b/Zend/tests/assign_ref_error_var_handling.phpt @@ -9,17 +9,22 @@ function val() { $var = 24; $arr = [PHP_INT_MAX => "foo"]; -var_dump($arr[] =& $var); +try { + var_dump($arr[] =& $var); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} var_dump(count($arr)); -var_dump($arr[] =& val()); +try { + var_dump($arr[] =& val()); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} var_dump(count($arr)); ?> ---EXPECTF-- -Warning: Cannot add element to the array as the next element is already occupied in %s on line %d -NULL +--EXPECT-- +Cannot add element to the array as the next element is already occupied int(1) - -Warning: Cannot add element to the array as the next element is already occupied in %s on line %d -NULL +Cannot add element to the array as the next element is already occupied int(1) diff --git a/Zend/tests/bug36303.phpt b/Zend/tests/bug36303.phpt index 1cec609b6b..50c473d320 100644 --- a/Zend/tests/bug36303.phpt +++ b/Zend/tests/bug36303.phpt @@ -2,13 +2,13 @@ Bug #36303 (foreach on error_zval produces segfault) --FILE-- "test"]; -foreach ($x[] as &$v) { +$x = []; +foreach ($x[[]] as &$v) { } echo "ok\n"; ?> --EXPECTF-- -Warning: Cannot add element to the array as the next element is already occupied in %s on line %d +Warning: Illegal offset type in %s on line %d Warning: Invalid argument supplied for foreach() in %s on line %d ok diff --git a/Zend/tests/bug47836.phpt b/Zend/tests/bug47836.phpt index 5a93a44c71..15afc68c48 100644 --- a/Zend/tests/bug47836.phpt +++ b/Zend/tests/bug47836.phpt @@ -4,12 +4,16 @@ Bug #47836 (array operator [] inconsistency when the array has PHP_INT_MAX index getMessage(), "\n"; +} var_dump($arr); ?> --EXPECTF-- -Warning: Cannot add element to the array as the next element is already occupied in %s on line 4 +Cannot add element to the array as the next element is already occupied array(1) { [%d]=> int(1) diff --git a/Zend/tests/bug52237.phpt b/Zend/tests/bug52237.phpt index 9f03a39b6f..97ea6d9ead 100644 --- a/Zend/tests/bug52237.phpt +++ b/Zend/tests/bug52237.phpt @@ -2,10 +2,10 @@ Bug #52237 (Crash when passing the reference of the property of a non-object) --FILE-- 'test']; -preg_match('//', '', $data[]); +$data = []; +preg_match('//', '', $data[[]]); var_dump(count($data)); ?> --EXPECTF-- -Warning: Cannot add element to the array as the next element is already occupied in %s on line %d -int(1) +Warning: Illegal offset type in %s on line %d +int(0) diff --git a/Zend/tests/bug69017.phpt b/Zend/tests/bug69017.phpt index 762fcbc9a0..d6d20d7c08 100644 --- a/Zend/tests/bug69017.phpt +++ b/Zend/tests/bug69017.phpt @@ -16,14 +16,18 @@ class c1 c1::$a1[] = 1; c1::$a2[] = 1; -c1::$a3[] = 1; +try { + c1::$a3[] = 1; +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} var_dump(c1::$a1); var_dump(c1::$a2); var_dump(c1::$a3); ?> --EXPECTF-- -Warning: Cannot add element to the array as the next element is already occupied in %sbug69017.php on line %d +Cannot add element to the array as the next element is already occupied array(2) { [1]=> string(3) "one" diff --git a/Zend/tests/bug71841.phpt b/Zend/tests/bug71841.phpt index f66761b3c9..35b805a2a7 100644 --- a/Zend/tests/bug71841.phpt +++ b/Zend/tests/bug71841.phpt @@ -1,23 +1,33 @@ --TEST-- Bug #71841 (EG(error_zval) is not handled well) ---INI-- -error_reporting=0 --FILE-- e.=0); -var_dump(++$z->x); -var_dump($z->y++); +@var_dump($z->e.=0); +@var_dump(++$z->x); +@var_dump($z->y++); $y = array(PHP_INT_MAX => 0); -var_dump($y[] .= 0); -var_dump(++$y[]); -var_dump($y[]++); +try { + var_dump($y[] .= 0); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} +try { + var_dump(++$y[]); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} +try { + var_dump($y[]++); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} ?> --EXPECT-- NULL NULL NULL -NULL -NULL -NULL +Cannot add element to the array as the next element is already occupied +Cannot add element to the array as the next element is already occupied +Cannot add element to the array as the next element is already occupied diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index 51c3583a52..0692993490 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -411,9 +411,9 @@ static int zend_ast_add_array_element(zval *result, zval *offset, zval *expr) switch (Z_TYPE_P(offset)) { case IS_UNDEF: if (!zend_hash_next_index_insert(Z_ARRVAL_P(result), expr)) { - zend_error(E_WARNING, + zend_throw_error(NULL, "Cannot add element to the array as the next element is already occupied"); - zval_ptr_dtor_nogc(expr); + return FAILURE; } break; case IS_STRING: @@ -458,8 +458,9 @@ static int zend_ast_add_unpacked_element(zval *result, zval *expr) { return FAILURE; } else { if (!zend_hash_next_index_insert(Z_ARRVAL_P(result), val)) { - zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); - break; + zend_throw_error(NULL, + "Cannot add element to the array as the next element is already occupied"); + return FAILURE; } Z_TRY_ADDREF_P(val); } diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index cc3db98d63..f8f2527256 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1892,7 +1892,7 @@ static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_use_scalar_as_array(v static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_cannot_add_element(void) { - zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); + zend_throw_error(NULL, "Cannot add element to the array as the next element is already occupied"); } static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_use_resource_as_offset(const zval *dim) diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index 410a6d0ed9..2ab3424bc6 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -1975,20 +1975,20 @@ static int zend_jit_cannot_add_element_stub(dasm_State **Dst) | SET_Z_TYPE_INFO FP + r0, IS_NULL |1: |.if X64WIN - | mov CARG1, E_WARNING + | xor CARG1, CARG1 | LOAD_ADDR CARG2, "Cannot add element to the array as the next element is already occupied" - | EXT_CALL zend_error, r0 + | EXT_CALL zend_throw_error, r0 | add r4, 0x28 |.elif X64 - | mov CARG1, E_WARNING + | xor CARG1, CARG1 | LOAD_ADDR CARG2, "Cannot add element to the array as the next element is already occupied" - | EXT_CALL zend_error, r0 + | EXT_CALL zend_throw_error, r0 | add r4, 8 |.else | sub r4, 8 | push "Cannot add element to the array as the next element is already occupied" - | push E_WARNING - | EXT_CALL zend_error, r0 + | push 0 + | EXT_CALL zend_throw_error, r0 | add r4, 28 |.endif | ret @@ -4644,7 +4644,7 @@ static int zend_jit_assign_dim(dasm_State **Dst, const zend_op *opline, zend_op_ | jz >1 |.cold_code |1: - | // zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); + | // zend_throw_error(NULL, "Cannot add element to the array as the next element is already occupied"); | CANNOT_ADD_ELEMENT opline | //ZEND_VM_C_GOTO(assign_dim_op_ret_null); | jmp >9 @@ -4880,7 +4880,7 @@ static int zend_jit_assign_dim_op(dasm_State **Dst, const zend_op *opline, zend_ | jz >1 |.cold_code |1: - | // zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); + | // zend_throw_error(NULL, "Cannot add element to the array as the next element is already occupied"); | CANNOT_ADD_ELEMENT opline | //ZEND_VM_C_GOTO(assign_dim_op_ret_null); | jmp >9 diff --git a/ext/opcache/tests/jit/assign_dim_002.phpt b/ext/opcache/tests/jit/assign_dim_002.phpt index 53e7aae81d..73792defa9 100644 --- a/ext/opcache/tests/jit/assign_dim_002.phpt +++ b/ext/opcache/tests/jit/assign_dim_002.phpt @@ -29,7 +29,11 @@ foo2(); function foo3() { $array = array(PHP_INT_MAX => "dummy"); - $array[] = array(); + try { + $array[] = array(); + } catch (Error $e) { + echo $e->getMessage(), "\n"; + } $array = new ArrayObject(); $array[index()] = 1; @@ -83,9 +87,8 @@ array(1) { array(0) { } } - -Warning: Cannot add element to the array as the next element is already occupied in %sassign_dim_002.php on line 22 -object(ArrayObject)#1 (1) { +Cannot add element to the array as the next element is already occupied +object(ArrayObject)#%d (1) { ["storage":"ArrayObject":private]=> array(2) { [2]=> @@ -104,7 +107,7 @@ array(1) { } } -Warning: Illegal offset type in %sassign_dim_002.php on line 47 +Warning: Illegal offset type in %sassign_dim_002.php on line 51 array(1) { [0]=> array(2) { @@ -124,5 +127,5 @@ array(1) { } } -Warning: Cannot use a scalar value as an array in %sassign_dim_002.php on line 57 +Warning: Cannot use a scalar value as an array in %sassign_dim_002.php on line 61 int(1)