Skip to content

Deprecate autovivification on false #7131

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 14 commits into from
Closed
4 changes: 2 additions & 2 deletions Zend/Optimizer/zend_inference.c
Original file line number Diff line number Diff line change
Expand Up @@ -4753,7 +4753,7 @@ ZEND_API int zend_may_throw_ex(const zend_op *opline, const zend_ssa_op *ssa_op,
return 1;
}
}
return (t1 & (MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_TRUE|MAY_BE_STRING|MAY_BE_LONG|MAY_BE_DOUBLE)) || opline->op2_type == IS_UNUSED ||
return (t1 & (MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_TRUE|MAY_BE_FALSE|MAY_BE_STRING|MAY_BE_LONG|MAY_BE_DOUBLE)) || opline->op2_type == IS_UNUSED ||
(t2 & (MAY_BE_UNDEF|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE));
case ZEND_ASSIGN_OBJ:
if (t1 & (MAY_BE_ANY-(MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_OBJECT))) {
Expand Down Expand Up @@ -4869,7 +4869,7 @@ ZEND_API int zend_may_throw_ex(const zend_op *opline, const zend_ssa_op *ssa_op,
return 0;
case ZEND_FETCH_DIM_W:
case ZEND_FETCH_LIST_W:
if (t1 & (MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE|MAY_BE_STRING|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF)) {
if (t1 & (MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE|MAY_BE_STRING|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF)) {
return 1;
}
if (t2 & (MAY_BE_RESOURCE|MAY_BE_ARRAY|MAY_BE_OBJECT)) {
Expand Down
194 changes: 194 additions & 0 deletions Zend/tests/falsetoarray.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
--TEST--
Autovivification of false to array
--FILE--
<?php

// control
$undef[] = 42;

// control
$null = null;
$null[] = 42;

// control
$false = false;
$false = [42];

print "[001]\n";
$false = false;
$false[] = 42;

print "[002]\n";
$ref = false;
$ref2 = &$ref;
$ref2[] = 42;

echo "\nFunction\n";
function ffalse(bool $a, ?bool $b, &$c, ...$d) {
print "[003]\n";
$a[] = 42;
print "[004]\n";
$b[] = 42;
print "[005]\n";
$c[] = 42;
print "[006]\n";
$d[0][] = 42;
}
$ref = false;
ffalse(false, false, $ref, false);

echo "\nProperties\n";
class Cfalse {
public $def;
private $untyped = false;
static private $st = false;
static private $st2 = false;
static private $st3 = false;
public function __construct(public $pu, private $pr = false) {
print "[007]\n";
$this->def = false;
$this->def[] = 42;
print "[008]\n";
$this->untyped[] = 42;
print "[009]\n";
self::$st[] = 42;
print "[010]\n";
static::$st2[] = 42;
print "[011]\n";
$this::$st3[] = 42;
print "[012]\n";
$this->pu[] = 42;
print "[013]\n";
$this->pr[] = 42;
}
}
new Cfalse(false, false);

echo "\nDestructuring\n";

print "[014]\n";
$add = false;
foreach ([42] as $add[]);

print "[015]\n";
$arr = false;
[$arr[]] = [42];

print "[016]\n";
$arr = [ 0 => [ 0 => false ] ];
$arr[0][0][0][] = 42;

print "[017]\n";
$false = false;
$r42 = 42;
$false[] &= $r42;

$false = false;
$false2 = false;
$false3 = false;
function &g(){
print "[018]\n";
global $false;
$false[] = 42;

$var1 = false;
$GLOBALS["false2"] =& $var1;

print "[019]\n";
$GLOBALS["false3"][] = 42;

print "[020]\n";
static $f2 = false;
return $f2;
}

$false = &g();
$false[] = 42;
print "[021]\n";
$false2[] = 42;

print "[022]\n";
$a = false;
unset($a[0][0]);

print "[023]\n";
$a = false;
unset($a[0]);

?>
--EXPECTF--
[001]

Deprecated: Automatic conversion of false to array is deprecated in %s
[002]

Deprecated: Automatic conversion of false to array is deprecated in %s

Function
[003]

Deprecated: Automatic conversion of false to array is deprecated in %s
[004]

Deprecated: Automatic conversion of false to array is deprecated in %s
[005]

Deprecated: Automatic conversion of false to array is deprecated in %s
[006]

Deprecated: Automatic conversion of false to array is deprecated in %s

Properties
[007]

Deprecated: Automatic conversion of false to array is deprecated in %s
[008]

Deprecated: Automatic conversion of false to array is deprecated in %s
[009]

Deprecated: Automatic conversion of false to array is deprecated in %s
[010]

Deprecated: Automatic conversion of false to array is deprecated in %s
[011]

Deprecated: Automatic conversion of false to array is deprecated in %s
[012]

Deprecated: Automatic conversion of false to array is deprecated in %s
[013]

Deprecated: Automatic conversion of false to array is deprecated in %s

Destructuring
[014]

Deprecated: Automatic conversion of false to array is deprecated in %s
[015]

Deprecated: Automatic conversion of false to array is deprecated in %s
[016]

Deprecated: Automatic conversion of false to array is deprecated in %s
[017]

Deprecated: Automatic conversion of false to array is deprecated in %s
[018]

Deprecated: Automatic conversion of false to array is deprecated in %s
[019]

Deprecated: Automatic conversion of false to array is deprecated in %s
[020]

Deprecated: Automatic conversion of false to array is deprecated in %s
[021]

Deprecated: Automatic conversion of false to array is deprecated in %s
[022]

Deprecated: Automatic conversion of false to array is deprecated in %s
[023]

Deprecated: Automatic conversion of false to array is deprecated in %s
10 changes: 9 additions & 1 deletion Zend/tests/indexing_001.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ foreach ($testvalues as $testvalue) {
}

?>
--EXPECT--
--EXPECTF--
*** Indexing - Testing value assignment with key ***
array(1) {
["foo"]=>
Expand All @@ -67,6 +67,8 @@ Cannot use a scalar value as an array
int(1)
Cannot use a scalar value as an array
bool(true)

Deprecated: Automatic conversion of false to array is deprecated in %s
array(1) {
["foo"]=>
array(1) {
Expand Down Expand Up @@ -102,6 +104,8 @@ Cannot use a scalar value as an array
int(1)
Cannot use a scalar value as an array
bool(true)

Deprecated: Automatic conversion of false to array is deprecated in %s
array(1) {
["foo"]=>
&array(1) {
Expand Down Expand Up @@ -132,6 +136,8 @@ Cannot use a scalar value as an array
int(1)
Cannot use a scalar value as an array
bool(true)

Deprecated: Automatic conversion of false to array is deprecated in %s
array(1) {
[0]=>
array(1) {
Expand Down Expand Up @@ -163,6 +169,8 @@ Cannot use a scalar value as an array
int(1)
Cannot use a scalar value as an array
bool(true)

Deprecated: Automatic conversion of false to array is deprecated in %s
array(1) {
[0]=>
&array(1) {
Expand Down
4 changes: 4 additions & 0 deletions Zend/tests/unset_non_array.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,17 @@ try {
?>
--EXPECTF--
Warning: Undefined variable $x in %s on line %d

Deprecated: Automatic conversion of false to array is deprecated in %s
Cannot unset offset in a non-array variable
Cannot unset offset in a non-array variable
Cannot unset offset in a non-array variable
Cannot unset string offsets
Cannot use object of type stdClass as array

Warning: Undefined variable $x in %s on line %d

Deprecated: Automatic conversion of false to array is deprecated in %s
Cannot unset offset in a non-array variable
Cannot unset offset in a non-array variable
Cannot unset offset in a non-array variable
Expand Down
8 changes: 8 additions & 0 deletions Zend/zend_execute.c
Original file line number Diff line number Diff line change
Expand Up @@ -1583,6 +1583,11 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_deprecated_function(const zend_functi
}
}

ZEND_API ZEND_COLD void ZEND_FASTCALL zend_false_to_array_deprecated(void)
{
zend_error(E_DEPRECATED, "Automatic conversion of false to array is deprecated");
}

static zend_never_inline void zend_assign_to_string_offset(zval *str, zval *dim, zval *value OPLINE_DC EXECUTE_DATA_DC)
{
zend_uchar c;
Expand Down Expand Up @@ -2330,6 +2335,9 @@ static zend_always_inline void zend_fetch_dimension_address(zval *result, zval *
if (type != BP_VAR_W && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
ZVAL_UNDEFINED_OP1();
}
if (Z_TYPE_P(container) == IS_FALSE) {
zend_false_to_array_deprecated();
}
if (type != BP_VAR_UNSET) {
array_init(container);
goto fetch_from_array;
Expand Down
1 change: 1 addition & 0 deletions Zend/zend_execute.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ extern ZEND_API const zend_internal_function zend_pass_function;

ZEND_API ZEND_COLD void ZEND_FASTCALL zend_missing_arg_error(zend_execute_data *execute_data);
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_deprecated_function(const zend_function *fbc);
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_false_to_array_deprecated(void);
ZEND_COLD void ZEND_FASTCALL zend_param_must_be_ref(const zend_function *func, uint32_t arg_num);

ZEND_API bool ZEND_FASTCALL zend_verify_ref_assignable_zval(zend_reference *ref, zval *zv, bool strict);
Expand Down
9 changes: 9 additions & 0 deletions Zend/zend_vm_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -1210,6 +1210,9 @@ ZEND_VM_C_LABEL(assign_dim_op_new_array):
if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) {
ZVAL_UNDEFINED_OP1();
}
if (Z_TYPE_P(container) == IS_FALSE) {
zend_false_to_array_deprecated();
}
ZVAL_ARR(container, zend_new_array(8));
ZEND_VM_C_GOTO(assign_dim_op_new_array);
} else {
Expand Down Expand Up @@ -2590,6 +2593,10 @@ ZEND_VM_C_LABEL(try_assign_dim_array):
FREE_OP_DATA();
}
} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
if (Z_TYPE_P(object_ptr) == IS_FALSE) {
zend_false_to_array_deprecated();
}

if (Z_ISREF_P(orig_object_ptr)
&& ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr))
&& !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
Expand Down Expand Up @@ -6453,6 +6460,8 @@ ZEND_VM_C_LABEL(num_index_dim):
zend_throw_error(NULL, "Cannot unset string offsets");
} else if (UNEXPECTED(Z_TYPE_P(container) > IS_FALSE)) {
zend_throw_error(NULL, "Cannot unset offset in a non-array variable");
} else if (UNEXPECTED(Z_TYPE_P(container) == IS_FALSE)) {
zend_false_to_array_deprecated();
}
} while (0);

Expand Down
Loading