Skip to content
Open
Show file tree
Hide file tree
Changes from 4 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
7 changes: 6 additions & 1 deletion Zend/Optimizer/sccp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1106,6 +1106,11 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o

if (op2) {
SKIP_IF_TOP(op2);
if (Z_TYPE_P(op2) == IS_NULL) {
/* Emits deprecation at run-time. */
SET_RESULT_BOT(result);
return;
}
}

/* We want to avoid keeping around intermediate arrays for each SSA variable in the
Expand Down Expand Up @@ -2290,7 +2295,7 @@ static int try_remove_definition(sccp_ctx *ctx, int var_num, zend_ssa_var *var,
break;
case ZEND_INIT_ARRAY:
case ZEND_ADD_ARRAY_ELEMENT:
if (opline->op2_type == IS_UNUSED) {
if (opline->op2_type == IS_UNUSED || opline->op2_type == IS_NULL) {
return 0;
}
/* break missing intentionally */
Expand Down
2 changes: 1 addition & 1 deletion Zend/Optimizer/zend_inference.c
Original file line number Diff line number Diff line change
Expand Up @@ -5252,7 +5252,7 @@ ZEND_API bool zend_may_throw_ex(const zend_op *opline, const zend_ssa_op *ssa_op
case ZEND_INIT_ARRAY:
return (opline->op2_type != IS_UNUSED) && (t2 & (MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE));
case ZEND_ADD_ARRAY_ELEMENT:
return (opline->op2_type == IS_UNUSED) || (t2 & (MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE));
return (opline->op2_type == IS_UNUSED) || (t2 & (MAY_BE_NULL|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE));
case ZEND_STRLEN:
return (t1 & MAY_BE_ANY) != MAY_BE_STRING;
case ZEND_COUNT:
Expand Down
2 changes: 2 additions & 0 deletions Zend/tests/constexpr/constant_expressions_dynamic.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ var_dump(
Warning: A non-numeric value encountered in %s on line %d

Deprecated: Implicit conversion from float 3.14 to int loses precision in %s on line %d

Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d
int(3)
string(4) "1foo"
bool(false)
Expand Down
15 changes: 15 additions & 0 deletions Zend/tests/offsets/gh20194.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
--TEST--
GH-20194: Using null as an array offset does not emit deprecation when resolved at compile time
--FILE--
<?php

$a = [null => 1];

echo $a[null];

?>
--EXPECTF--
Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d

Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d
1
10 changes: 7 additions & 3 deletions Zend/zend_API.c
Original file line number Diff line number Diff line change
Expand Up @@ -2255,9 +2255,6 @@ ZEND_API zend_result array_set_zval_key(HashTable *ht, zval *key, zval *value) /
case IS_STRING:
result = zend_symtable_update(ht, Z_STR_P(key), value);
break;
case IS_NULL:
result = zend_hash_update(ht, ZSTR_EMPTY_ALLOC(), value);
break;
case IS_RESOURCE:
zend_use_resource_as_offset(key);
result = zend_hash_index_update(ht, Z_RES_HANDLE_P(key), value);
Expand All @@ -2274,6 +2271,13 @@ ZEND_API zend_result array_set_zval_key(HashTable *ht, zval *key, zval *value) /
case IS_DOUBLE:
result = zend_hash_index_update(ht, zend_dval_to_lval_safe(Z_DVAL_P(key)), value);
break;
case IS_NULL:
zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead");
if (UNEXPECTED(EG(exception))) {
return FAILURE;
}
result = zend_hash_update(ht, ZSTR_EMPTY_ALLOC(), value);
break;
default:
zend_illegal_container_offset(ZSTR_KNOWN(ZEND_STR_ARRAY), key, BP_VAR_W);
result = NULL;
Expand Down
9 changes: 4 additions & 5 deletions Zend/zend_compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -10175,9 +10175,7 @@ static bool zend_try_ct_eval_array(zval *result, zend_ast *ast) /* {{{ */
zend_long lval = zend_dval_to_lval_silent(Z_DVAL_P(key));
/* Incompatible float will generate an error, leave this to run-time */
if (!zend_is_long_compatible(Z_DVAL_P(key), lval)) {
zval_ptr_dtor_nogc(value);
zval_ptr_dtor(result);
return 0;
goto fail;
}
zend_hash_index_update(Z_ARRVAL_P(result), lval, value);
break;
Expand All @@ -10189,13 +10187,14 @@ static bool zend_try_ct_eval_array(zval *result, zend_ast *ast) /* {{{ */
zend_hash_index_update(Z_ARRVAL_P(result), 1, value);
break;
case IS_NULL:
zend_hash_update(Z_ARRVAL_P(result), ZSTR_EMPTY_ALLOC(), value);
break;
/* Null key will generate a warning at run-time. */
goto fail;
default:
zend_error_noreturn(E_COMPILE_ERROR, "Illegal offset type");
break;
}
} else if (!zend_hash_next_index_insert(Z_ARRVAL_P(result), value)) {
fail:
zval_ptr_dtor_nogc(value);
zval_ptr_dtor(result);
return 0;
Expand Down
6 changes: 5 additions & 1 deletion Zend/zend_vm_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -6278,7 +6278,11 @@ ZEND_VM_C_LABEL(num_index):
} else if ((OP2_TYPE & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
offset = Z_REFVAL_P(offset);
ZEND_VM_C_GOTO(add_again);
} else if (Z_TYPE_P(offset) == IS_NULL) {
} else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) {
zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead");
if (UNEXPECTED(EG(exception))) {
HANDLE_EXCEPTION();
}
str = ZSTR_EMPTY_ALLOC();
ZEND_VM_C_GOTO(str_index);
} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
Expand Down
Loading
Loading