Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ PHP NEWS
with chained Pi nodes). (ndossche)
. Fixed JIT treating an array as packed after a string key write turned it
into a hash. (jorgsowa)
. Fixed function JIT ASSIGN_DIM reporting an undefined value or key out of
order, or when the VM does not, on non-array containers. (jorgsowa)

- PDO:
. Fixed invalid ATTR_ORACLE_NULLS values being accepted and truncated.
Expand Down
27 changes: 15 additions & 12 deletions ext/opcache/jit/zend_jit_helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -1510,13 +1510,6 @@ static void ZEND_FASTCALL zend_jit_assign_dim_helper(zval *object_ptr, zval *dim
return;
}

if (UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
const zend_op *op_data = EG(current_execute_data)->opline + 1;
ZEND_ASSERT(op_data->opcode == ZEND_OP_DATA && op_data->op1_type == IS_CV);
zend_jit_undefined_op_helper(op_data->op1.var);
value = &EG(uninitialized_zval);
}

if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
zend_throw_error(NULL, "[] operator not supported for strings");
if (result) {
Expand Down Expand Up @@ -1546,16 +1539,26 @@ static void ZEND_FASTCALL zend_jit_assign_dim_helper(zval *object_ptr, zval *dim
return;
}

if (UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
/* EX(opline) no longer points to ASSIGN_DIM after a throw; the VM skips the warning too. */
if (EXPECTED(!EG(exception))) {
const zend_op *op_data = EG(current_execute_data)->opline + 1;
ZEND_ASSERT(op_data->opcode == ZEND_OP_DATA && op_data->op1_type == IS_CV);
if (!zend_jit_undefined_op_helper_write(arr, op_data->op1.var)) {
if (result) {
ZVAL_UNDEF(result);
}
return;
}
}
value = &EG(uninitialized_zval);
}

ZVAL_COPY_DEREF(var, value);
if (result) {
ZVAL_COPY(result, var);
}
} else {
if (dim && UNEXPECTED(Z_TYPE_P(dim) == IS_UNDEF)) {
const zend_op *opline = EG(current_execute_data)->opline;
zend_jit_undefined_op_helper(opline->op2.var);
dim = &EG(uninitialized_zval);
}
zend_throw_error(NULL, "Cannot use a scalar value as an array");
if (result) {
ZVAL_UNDEF(result);
Expand Down
21 changes: 21 additions & 0 deletions ext/opcache/tests/jit/assign_dim_undef_op_data_001.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
--TEST--
JIT ASSIGN_DIM: undefined OP_DATA is not read when the container is a scalar
--INI--
opcache.enable=1
opcache.enable_cli=1
opcache.file_update_protection=0
opcache.jit=function
--FILE--
<?php
function test() {
$x = 1.5;
$x[0] = $undef;
}
try {
test();
} catch (Error $e) {
echo $e::class, ": ", $e->getMessage(), "\n";
}
?>
--EXPECT--
Error: Cannot use a scalar value as an array
21 changes: 21 additions & 0 deletions ext/opcache/tests/jit/assign_dim_undef_op_data_002.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
--TEST--
JIT ASSIGN_DIM: undefined dim is not reported when the container is a scalar
--INI--
opcache.enable=1
opcache.enable_cli=1
opcache.file_update_protection=0
opcache.jit=function
--FILE--
<?php
function test() {
$x = 1.5;
$x[$undef] = 1;
}
try {
test();
} catch (Error $e) {
echo $e::class, ": ", $e->getMessage(), "\n";
}
?>
--EXPECT--
Error: Cannot use a scalar value as an array
21 changes: 21 additions & 0 deletions ext/opcache/tests/jit/assign_dim_undef_op_data_003.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
--TEST--
JIT ASSIGN_DIM: undefined OP_DATA is not read when appending to a string
--INI--
opcache.enable=1
opcache.enable_cli=1
opcache.file_update_protection=0
opcache.jit=function
--FILE--
<?php
function test() {
$x = 'ab';
$x[] = $undef;
}
try {
test();
} catch (Error $e) {
echo $e::class, ": ", $e->getMessage(), "\n";
}
?>
--EXPECT--
Error: [] operator not supported for strings
24 changes: 24 additions & 0 deletions ext/opcache/tests/jit/assign_dim_undef_op_data_004.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
--TEST--
JIT ASSIGN_DIM: undefined OP_DATA is reported after the false to array deprecation
--INI--
opcache.enable=1
opcache.enable_cli=1
opcache.file_update_protection=0
opcache.jit=function
--FILE--
<?php
function test() {
$x = false;
$x[0] = $undef;
var_dump($x);
}
test();
?>
--EXPECTF--
Deprecated: Automatic conversion of false to array is deprecated in %s on line %d

Warning: Undefined variable $undef in %s on line %d
array(1) {
[0]=>
NULL
}
24 changes: 24 additions & 0 deletions ext/opcache/tests/jit/assign_dim_undef_op_data_005.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
--TEST--
JIT ASSIGN_DIM: undefined OP_DATA is reported after the false to array deprecation when appending
--INI--
opcache.enable=1
opcache.enable_cli=1
opcache.file_update_protection=0
opcache.jit=function
--FILE--
<?php
function test() {
$x = false;
$x[] = $undef;
var_dump($x);
}
test();
?>
--EXPECTF--
Deprecated: Automatic conversion of false to array is deprecated in %s on line %d

Warning: Undefined variable $undef in %s on line %d
array(1) {
[0]=>
NULL
}
26 changes: 26 additions & 0 deletions ext/opcache/tests/jit/assign_dim_undef_op_data_006.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
--TEST--
JIT ASSIGN_DIM: undefined dim is reported before undefined OP_DATA when the container is false
--INI--
opcache.enable=1
opcache.enable_cli=1
opcache.file_update_protection=0
opcache.jit=function
--FILE--
<?php
function test() {
$x = false;
$x[$undefKey] = $undef;
var_dump($x);
}
test();
?>
--EXPECTF--
Deprecated: Automatic conversion of false to array is deprecated in %s on line %d

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

Warning: Undefined variable $undef in %s on line %d
array(1) {
[""]=>
NULL
}
24 changes: 24 additions & 0 deletions ext/opcache/tests/jit/assign_dim_undef_op_data_007.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
--TEST--
JIT ASSIGN_DIM: undefined OP_DATA is not reported when the false to array deprecation throws
--INI--
opcache.enable=1
opcache.enable_cli=1
opcache.file_update_protection=0
opcache.jit=function
--FILE--
<?php
set_error_handler(function ($_, $msg) {
throw new Exception($msg);
});
function test() {
$x = false;
$x[0] = $undef;
}
try {
test();
} catch (Exception $e) {
echo $e::class, ": ", $e->getMessage(), "\n";
}
?>
--EXPECT--
Exception: Automatic conversion of false to array is deprecated
27 changes: 27 additions & 0 deletions ext/opcache/tests/jit/assign_dim_undef_op_data_008.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
--TEST--
JIT ASSIGN_DIM: container converted from false is overwritten while reporting undefined OP_DATA
--INI--
opcache.enable=1
opcache.enable_cli=1
opcache.file_update_protection=0
opcache.jit=function
--FILE--
<?php
set_error_handler(function ($_, $msg) {
echo $msg, "\n";
if (str_starts_with($msg, 'Undefined variable')) {
$GLOBALS['x'] = 1;
}
});
function test() {
global $x;
$x = false;
$x[0] = $undef;
}
test();
var_dump($x);
?>
--EXPECT--
Automatic conversion of false to array is deprecated
Undefined variable $undef
int(1)
Loading