. Fixed bug #76439 (Changed behaviour in unclosed HereDoc). (Nikita, tpunt)
. Added syslog.facility and syslog.ident INI entries for customizing syslog
logging. (Philip Prindeville)
+ . Fixed bug #63217 (Constant numeric strings become integers when used as
+ ArrayAccess offset). (Rudi Theunissen)
- DOM:
. Fixed bug #76285 (DOMDocument::formatOutput attribute sometimes ignored).
the following "FOO;" will cause a syntax error. This issue can always be
resolved by choosing an ending label that does not occur within the contents
of the string.
+ . Array accesses of type $obj["123"], where $obj implements ArrayAccess and
+ "123" is an integral string literal will no longer result in an implicit
+ conversion to integer, i.e., $obj->offsetGet("123") will be called instead
+ of $obj->offsetGet(123). This matches existing behavior for non-literals.
+ The behavior of arrays is not affected in any way, they continue to
+ implicitly convert integeral string keys to integers.
. In PHP, static properties are shared between inheriting classes, unless the
static property is explicitly overridden in a child class. However, due to
an implementation artifact it was possible to separate the static properties
<?php
$x = "bug";
var_dump(isset($x[-10]));
+var_dump(isset($x[1]));
var_dump(isset($x["1"]));
-echo $x["1"]."\n";
+var_dump($x[-10])."\n";
+var_dump($x[1])."\n";
+var_dump($x["1"])."\n";
?>
---EXPECT--
+--EXPECTF--
bool(false)
bool(true)
-u
+bool(true)
+
+Notice: Uninitialized string offset: -10 in %s on line 6
+string(0) ""
+string(1) "u"
+string(1) "u"
print_r($array);
$array = array(1 => 2);
-$a = 1;
+
unset($array["1"]);
print_r($array);
?>
--- /dev/null
+--TEST--
+Bug #63217 (Constant numeric strings become integers when used as ArrayAccess offset)
+--INI--
+opcache.enable_cli=1
+opcache.enable=1
+opcache.optimization_level=-1
+--FILE--
+<?php
+class Test implements ArrayAccess {
+ public function offsetExists($offset) {
+ echo "offsetExists given ";
+ var_dump($offset);
+ }
+ public function offsetUnset($offset) {
+ echo "offsetUnset given ";
+ var_dump($offset);
+ }
+ public function offsetSet($offset, $value) {
+ echo "offsetSet given ";
+ var_dump($offset);
+ }
+ public function offsetGet($offset) {
+ echo "offsetGet given ";
+ var_dump($offset);
+ }
+}
+
+$test = new Test;
+
+/* These should all produce string(...) "..." output and not int(...) */
+isset($test['0']);
+isset($test['123']);
+unset($test['0']);
+unset($test['123']);
+$test['0'] = true;
+$test['123'] = true;
+$foo = $test['0'];
+$foo = $test['123'];
+
+/* These caused the same bug, but in opcache rather than the compiler */
+isset($test[(string)'0']);
+isset($test[(string)'123']);
+unset($test[(string)'0']);
+unset($test[(string)'123']);
+$test[(string)'0'] = true;
+$test[(string)'123'] = true;
+$foo = $test[(string)'0'];
+$foo = $test[(string)'123'];
+
+/**
+ * @see https://github.com/php/php-src/pull/2607#issuecomment-313781748
+ */
+function test(): string {
+ $array["10"] = 42;
+ foreach ($array as $key => $value) {
+ return $key;
+ }
+}
+
+var_dump(test());
+
+/**
+ * Make sure we don't break arrays.
+ */
+$array = [];
+
+$key = '123';
+
+$array[$key] = 1;
+$array['321'] = 2;
+$array['abc'] = 3;
+
+var_dump($array);
+
+/**
+ * Make sure that we haven't broken ArrayObject
+ */
+$ao = new ArrayObject();
+
+$key = '123';
+
+$ao = [];
+$ao[$key] = 1;
+$ao['321'] = 2;
+$ao['abc'] = 3;
+
+var_dump($ao);
+
+?>
+--EXPECT--
+offsetExists given string(1) "0"
+offsetExists given string(3) "123"
+offsetUnset given string(1) "0"
+offsetUnset given string(3) "123"
+offsetSet given string(1) "0"
+offsetSet given string(3) "123"
+offsetGet given string(1) "0"
+offsetGet given string(3) "123"
+offsetExists given string(1) "0"
+offsetExists given string(3) "123"
+offsetUnset given string(1) "0"
+offsetUnset given string(3) "123"
+offsetSet given string(1) "0"
+offsetSet given string(3) "123"
+offsetGet given string(1) "0"
+offsetGet given string(3) "123"
+string(2) "10"
+array(3) {
+ [123]=>
+ int(1)
+ [321]=>
+ int(2)
+ ["abc"]=>
+ int(3)
+}
+array(3) {
+ [123]=>
+ int(1)
+ [321]=>
+ int(2)
+ ["abc"]=>
+ int(3)
+}
var_dump(empty($str[8]));
var_dump(empty($str[10000]));
// non-numeric offsets
-print "- string ---\n";
-var_dump(empty($str['-1']));
+print "- string literal ---\n";
+var_dump(empty($str['-1'])); // 3
var_dump(empty($str['-10']));
-var_dump(empty($str['-4'])); // 0
var_dump(empty($str['0']));
var_dump(empty($str['1']));
var_dump(empty($str['4'])); // 0
var_dump(empty($str['1.5']));
var_dump(empty($str['good']));
var_dump(empty($str['3 and a half']));
+print "- string variable ---\n";
+var_dump(empty($str[$key = '-1'])); // 3
+var_dump(empty($str[$key = '-10']));
+var_dump(empty($str[$key = '0']));
+var_dump(empty($str[$key = '1']));
+var_dump(empty($str[$key = '4'])); // 0
+var_dump(empty($str[$key = '1.5']));
+var_dump(empty($str[$key = 'good']));
+var_dump(empty($str[$key = '3 and a half']));
print "- bool ---\n";
var_dump(empty($str[true]));
var_dump(empty($str[false]));
print "done\n";
?>
---EXPECT--
+--EXPECTF--
- empty ---
bool(false)
bool(true)
bool(false)
bool(true)
bool(true)
-- string ---
+- string literal ---
bool(false)
bool(true)
+bool(false)
+bool(false)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+- string variable ---
+bool(false)
bool(true)
bool(false)
bool(false)
var_dump(isset($str[8]));
var_dump(isset($str[10000]));
// non-numeric offsets
-print "- string ---\n";
-var_dump(isset($str['-1']));
+print "- string literal ---\n";
+var_dump(isset($str['-1'])); // 3
var_dump(isset($str['-10']));
var_dump(isset($str['0']));
var_dump(isset($str['1']));
var_dump(isset($str['1.5']));
var_dump(isset($str['good']));
var_dump(isset($str['3 and a half']));
+print "- string variable ---\n";
+var_dump(isset($str[$key = '-1'])); // 3
+var_dump(isset($str[$key = '-10']));
+var_dump(isset($str[$key = '0']));
+var_dump(isset($str[$key = '1']));
+var_dump(isset($str[$key = '4'])); // 0
+var_dump(isset($str[$key = '1.5']));
+var_dump(isset($str[$key = 'good']));
+var_dump(isset($str[$key = '3 and a half']));
print "- bool ---\n";
var_dump(isset($str[true]));
var_dump(isset($str[false]));
print "done\n";
?>
---EXPECT--
+--EXPECTF--
- isset ---
bool(true)
bool(false)
bool(true)
bool(false)
bool(false)
-- string ---
+- string literal ---
+bool(true)
+bool(false)
+bool(true)
+bool(true)
+bool(true)
+bool(false)
+bool(false)
+bool(false)
+- string variable ---
bool(true)
bool(false)
bool(true)
dim_node.op_type = IS_UNUSED;
} else {
zend_compile_expr(&dim_node, dim_ast);
- zend_handle_numeric_op(&dim_node);
}
opline = zend_delayed_emit_op(result, ZEND_FETCH_DIM_R, &var_node, &dim_node);
}
} else if (EXPECTED(Z_TYPE_P(dim) == IS_STRING)) {
offset_key = Z_STR_P(dim);
- if (dim_type != IS_CONST) {
- if (ZEND_HANDLE_NUMERIC(offset_key, hval)) {
- goto num_index;
- }
+ if (ZEND_HANDLE_NUMERIC(offset_key, hval)) {
+ goto num_index;
}
str_index:
retval = zend_hash_find_ex(ht, offset_key, dim_type == IS_CONST);
ZEND_VM_C_LABEL(offset_again):
if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
key = Z_STR_P(offset);
- if (OP2_TYPE != IS_CONST) {
- if (ZEND_HANDLE_NUMERIC(key, hval)) {
- ZEND_VM_C_GOTO(num_index_dim);
- }
+ if (ZEND_HANDLE_NUMERIC(key, hval)) {
+ ZEND_VM_C_GOTO(num_index_dim);
}
ZEND_VM_C_LABEL(str_index_dim):
if (ht == &EG(symbol_table)) {
ZEND_VM_C_LABEL(isset_again):
if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
str = Z_STR_P(offset);
- if (OP2_TYPE != IS_CONST) {
- if (ZEND_HANDLE_NUMERIC(str, hval)) {
- ZEND_VM_C_GOTO(num_index_prop);
- }
+ if (ZEND_HANDLE_NUMERIC(str, hval)) {
+ ZEND_VM_C_GOTO(num_index_prop);
}
value = zend_hash_find_ex_ind(ht, str, OP2_TYPE == IS_CONST);
} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
isset_again:
if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
str = Z_STR_P(offset);
- if (IS_CONST != IS_CONST) {
- if (ZEND_HANDLE_NUMERIC(str, hval)) {
- goto num_index_prop;
- }
+ if (ZEND_HANDLE_NUMERIC(str, hval)) {
+ goto num_index_prop;
}
value = zend_hash_find_ex_ind(ht, str, IS_CONST == IS_CONST);
} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
isset_again:
if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
str = Z_STR_P(offset);
- if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
- if (ZEND_HANDLE_NUMERIC(str, hval)) {
- goto num_index_prop;
- }
+ if (ZEND_HANDLE_NUMERIC(str, hval)) {
+ goto num_index_prop;
}
value = zend_hash_find_ex_ind(ht, str, (IS_TMP_VAR|IS_VAR) == IS_CONST);
} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
isset_again:
if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
str = Z_STR_P(offset);
- if (IS_CV != IS_CONST) {
- if (ZEND_HANDLE_NUMERIC(str, hval)) {
- goto num_index_prop;
- }
+ if (ZEND_HANDLE_NUMERIC(str, hval)) {
+ goto num_index_prop;
}
value = zend_hash_find_ex_ind(ht, str, IS_CV == IS_CONST);
} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
isset_again:
if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
str = Z_STR_P(offset);
- if (IS_CONST != IS_CONST) {
- if (ZEND_HANDLE_NUMERIC(str, hval)) {
- goto num_index_prop;
- }
+ if (ZEND_HANDLE_NUMERIC(str, hval)) {
+ goto num_index_prop;
}
value = zend_hash_find_ex_ind(ht, str, IS_CONST == IS_CONST);
} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
isset_again:
if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
str = Z_STR_P(offset);
- if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
- if (ZEND_HANDLE_NUMERIC(str, hval)) {
- goto num_index_prop;
- }
+ if (ZEND_HANDLE_NUMERIC(str, hval)) {
+ goto num_index_prop;
}
value = zend_hash_find_ex_ind(ht, str, (IS_TMP_VAR|IS_VAR) == IS_CONST);
} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
isset_again:
if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
str = Z_STR_P(offset);
- if (IS_CV != IS_CONST) {
- if (ZEND_HANDLE_NUMERIC(str, hval)) {
- goto num_index_prop;
- }
+ if (ZEND_HANDLE_NUMERIC(str, hval)) {
+ goto num_index_prop;
}
value = zend_hash_find_ex_ind(ht, str, IS_CV == IS_CONST);
} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
offset_again:
if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
key = Z_STR_P(offset);
- if (IS_CONST != IS_CONST) {
- if (ZEND_HANDLE_NUMERIC(key, hval)) {
- goto num_index_dim;
- }
+ if (ZEND_HANDLE_NUMERIC(key, hval)) {
+ goto num_index_dim;
}
str_index_dim:
if (ht == &EG(symbol_table)) {
offset_again:
if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
key = Z_STR_P(offset);
- if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
- if (ZEND_HANDLE_NUMERIC(key, hval)) {
- goto num_index_dim;
- }
+ if (ZEND_HANDLE_NUMERIC(key, hval)) {
+ goto num_index_dim;
}
str_index_dim:
if (ht == &EG(symbol_table)) {
offset_again:
if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
key = Z_STR_P(offset);
- if (IS_CV != IS_CONST) {
- if (ZEND_HANDLE_NUMERIC(key, hval)) {
- goto num_index_dim;
- }
+ if (ZEND_HANDLE_NUMERIC(key, hval)) {
+ goto num_index_dim;
}
str_index_dim:
if (ht == &EG(symbol_table)) {
offset_again:
if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
key = Z_STR_P(offset);
- if (IS_CONST != IS_CONST) {
- if (ZEND_HANDLE_NUMERIC(key, hval)) {
- goto num_index_dim;
- }
+ if (ZEND_HANDLE_NUMERIC(key, hval)) {
+ goto num_index_dim;
}
str_index_dim:
if (ht == &EG(symbol_table)) {
isset_again:
if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
str = Z_STR_P(offset);
- if (IS_CONST != IS_CONST) {
- if (ZEND_HANDLE_NUMERIC(str, hval)) {
- goto num_index_prop;
- }
+ if (ZEND_HANDLE_NUMERIC(str, hval)) {
+ goto num_index_prop;
}
value = zend_hash_find_ex_ind(ht, str, IS_CONST == IS_CONST);
} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
offset_again:
if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
key = Z_STR_P(offset);
- if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
- if (ZEND_HANDLE_NUMERIC(key, hval)) {
- goto num_index_dim;
- }
+ if (ZEND_HANDLE_NUMERIC(key, hval)) {
+ goto num_index_dim;
}
str_index_dim:
if (ht == &EG(symbol_table)) {
isset_again:
if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
str = Z_STR_P(offset);
- if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
- if (ZEND_HANDLE_NUMERIC(str, hval)) {
- goto num_index_prop;
- }
+ if (ZEND_HANDLE_NUMERIC(str, hval)) {
+ goto num_index_prop;
}
value = zend_hash_find_ex_ind(ht, str, (IS_TMP_VAR|IS_VAR) == IS_CONST);
} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
offset_again:
if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
key = Z_STR_P(offset);
- if (IS_CV != IS_CONST) {
- if (ZEND_HANDLE_NUMERIC(key, hval)) {
- goto num_index_dim;
- }
+ if (ZEND_HANDLE_NUMERIC(key, hval)) {
+ goto num_index_dim;
}
str_index_dim:
if (ht == &EG(symbol_table)) {
isset_again:
if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
str = Z_STR_P(offset);
- if (IS_CV != IS_CONST) {
- if (ZEND_HANDLE_NUMERIC(str, hval)) {
- goto num_index_prop;
- }
+ if (ZEND_HANDLE_NUMERIC(str, hval)) {
+ goto num_index_prop;
}
value = zend_hash_find_ex_ind(ht, str, IS_CV == IS_CONST);
} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
}
#endif
+
+#define DIM_OP_FOR_CONST_NUM_CHECK \
+ (opline->op2_type == IS_CONST ? CRT_CONSTANT_EX(op_array, opline, opline->op2, ssa->rt_constants) : NULL)
+
static void zend_ssa_check_scc_var(const zend_op_array *op_array, zend_ssa *ssa, int var, int *index, int *dfs, int *root, zend_worklist_stack *stack) /* {{{ */
{
#ifdef SYM_RANGE
return tmp;
}
+static inline uint32_t get_dim_array_key_type(uint32_t dim_type, zend_uchar dim_op_type, zval *dim_op)
+{
+ uint32_t tmp = 0;
+
+ if (dim_op_type == IS_UNUSED) {
+ tmp |= MAY_BE_ARRAY_KEY_LONG;
+ } else {
+ if (dim_type & (MAY_BE_LONG|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_RESOURCE|MAY_BE_DOUBLE)) {
+ tmp |= MAY_BE_ARRAY_KEY_LONG;
+ }
+ if (dim_type & MAY_BE_STRING) {
+ if (dim_op_type != IS_CONST) {
+ tmp |= MAY_BE_ARRAY_KEY_STRING | MAY_BE_ARRAY_KEY_LONG;
+ } else {
+ zend_ulong hval;
+ if (ZEND_HANDLE_NUMERIC(Z_STR_P(dim_op), hval)) {
+ tmp |= MAY_BE_ARRAY_KEY_LONG;
+ } else {
+ tmp |= MAY_BE_ARRAY_KEY_STRING;
+ }
+ }
+ }
+ if (dim_type & (MAY_BE_UNDEF|MAY_BE_NULL)) {
+ tmp |= MAY_BE_ARRAY_KEY_STRING;
+ }
+ }
+
+ return tmp;
+}
+
static uint32_t assign_dim_result_type(
- uint32_t arr_type, uint32_t dim_type, uint32_t value_type, zend_uchar dim_op_type) {
+ uint32_t arr_type,
+ uint32_t dim_type,
+ uint32_t value_type,
+ zend_uchar dim_op_type,
+ zval *dim_op
+) {
uint32_t tmp = arr_type & ~(MAY_BE_RC1|MAY_BE_RCN);
if (arr_type & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_FALSE)) {
if (value_type & MAY_BE_UNDEF) {
tmp |= MAY_BE_ARRAY_OF_NULL;
}
- if (dim_op_type == IS_UNUSED) {
- tmp |= MAY_BE_ARRAY_KEY_LONG;
- } else {
- if (dim_type & (MAY_BE_LONG|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_RESOURCE|MAY_BE_DOUBLE)) {
- tmp |= MAY_BE_ARRAY_KEY_LONG;
- }
- if (dim_type & MAY_BE_STRING) {
- tmp |= MAY_BE_ARRAY_KEY_STRING;
- if (dim_op_type != IS_CONST) {
- // FIXME: numeric string
- tmp |= MAY_BE_ARRAY_KEY_LONG;
- }
- }
- if (dim_type & (MAY_BE_UNDEF|MAY_BE_NULL)) {
- tmp |= MAY_BE_ARRAY_KEY_STRING;
- }
- }
+ tmp |= get_dim_array_key_type(dim_type, dim_op_type, dim_op);
}
return tmp;
}
if (opline->extended_value == ZEND_ASSIGN_DIM) {
if (opline->op1_type == IS_CV) {
- orig = assign_dim_result_type(orig, OP2_INFO(), tmp, opline->op2_type);
+ orig = assign_dim_result_type(orig, OP2_INFO(), tmp, opline->op2_type, DIM_OP_FOR_CONST_NUM_CHECK);
+
UPDATE_SSA_TYPE(orig, ssa_ops[i].op1_def);
COPY_SSA_OBJ_TYPE(ssa_ops[i].op1_use, ssa_ops[i].op1_def);
}
break;
case ZEND_ASSIGN_DIM:
if (opline->op1_type == IS_CV) {
- tmp = assign_dim_result_type(t1, t2, OP1_DATA_INFO(), opline->op2_type);
+ tmp = assign_dim_result_type(t1, t2, OP1_DATA_INFO(), opline->op2_type, DIM_OP_FOR_CONST_NUM_CHECK);
+
UPDATE_SSA_TYPE(tmp, ssa_ops[i].op1_def);
COPY_SSA_OBJ_TYPE(ssa_ops[i].op1_use, ssa_ops[i].op1_def);
}
if (ssa_ops[i].result_use >= 0) {
tmp |= ssa_var_info[ssa_ops[i].result_use].type;
}
- if (opline->op2_type == IS_UNUSED) {
- tmp |= MAY_BE_ARRAY_KEY_LONG;
- } else {
- if (t2 & (MAY_BE_LONG|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_DOUBLE)) {
- tmp |= MAY_BE_ARRAY_KEY_LONG;
- }
- if (t2 & (MAY_BE_STRING)) {
- tmp |= MAY_BE_ARRAY_KEY_STRING;
- if (opline->op2_type != IS_CONST) {
- // FIXME: numeric string
- tmp |= MAY_BE_ARRAY_KEY_LONG;
- }
- }
- if (t2 & (MAY_BE_UNDEF | MAY_BE_NULL)) {
- tmp |= MAY_BE_ARRAY_KEY_STRING;
- }
- }
+ tmp |= get_dim_array_key_type(t2, opline->op2_type, DIM_OP_FOR_CONST_NUM_CHECK);
+
UPDATE_SSA_TYPE(tmp, ssa_ops[i].result_def);
}
break;
if (t1 & (MAY_BE_OBJECT|MAY_BE_RESOURCE)) {
tmp |= t1 & (MAY_BE_RC1|MAY_BE_RCN);
}
- if (opline->op2_type == IS_UNUSED) {
- tmp |= MAY_BE_ARRAY_KEY_LONG;
- } else {
- if (t2 & (MAY_BE_LONG|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_RESOURCE|MAY_BE_DOUBLE)) {
- tmp |= MAY_BE_ARRAY_KEY_LONG;
- }
- if (t2 & MAY_BE_STRING) {
- tmp |= MAY_BE_ARRAY_KEY_STRING;
- if (opline->op2_type != IS_CONST) {
- // FIXME: numeric string
- tmp |= MAY_BE_ARRAY_KEY_LONG;
- }
- }
- if (t2 & (MAY_BE_UNDEF | MAY_BE_NULL)) {
- tmp |= MAY_BE_ARRAY_KEY_STRING;
- }
- }
+ tmp |= get_dim_array_key_type(t2, opline->op2_type, DIM_OP_FOR_CONST_NUM_CHECK);
+
} else if (opline->opcode == ZEND_FETCH_DIM_UNSET) {
if (t1 & MAY_BE_ARRAY) {
tmp |= MAY_BE_RC1;
opline->op2.constant = zend_optimizer_add_literal(op_array, val);
}
break;
- case ZEND_ISSET_ISEMPTY_DIM_OBJ:
case ZEND_ADD_ARRAY_ELEMENT:
- case ZEND_INIT_ARRAY:
- case ZEND_ASSIGN_DIM:
- case ZEND_UNSET_DIM:
- case ZEND_FETCH_DIM_R:
- case ZEND_FETCH_DIM_W:
- case ZEND_FETCH_DIM_RW:
- case ZEND_FETCH_DIM_IS:
- case ZEND_FETCH_DIM_FUNC_ARG:
- case ZEND_FETCH_DIM_UNSET:
- case ZEND_FETCH_LIST_R:
- case ZEND_FETCH_LIST_W:
if (Z_TYPE_P(val) == IS_STRING) {
zend_ulong index;
if (ZEND_HANDLE_NUMERIC(Z_STR_P(val), index)) {