Skip to content

Commit 99fa740

Browse files
authored
Use common function for TypeError on illegal offset access (#10544)
This merges all usages of emitting an offset TypeError into a new ZEND_API function zend_illegal_container_offset(const zend_string* container, const zval *offset, int type); Where the container should represent the type on which the access is attempted (e.g. string, array) The offset zval that is used, where the error message will display its type The type of access, which should be a BP_VAR_* constant, to get special message for isset/empty/unset
1 parent ab77485 commit 99fa740

26 files changed

+130
-146
lines changed

Zend/tests/036.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@ try {
1111

1212
?>
1313
--EXPECT--
14-
Cannot access offset of type object on array
14+
Cannot access offset of type Closure on array

Zend/tests/038.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@ try {
1111

1212
?>
1313
--EXPECT--
14-
Cannot access offset of type object on array
14+
Cannot access offset of type Closure on array

Zend/tests/assign_dim_obj_null_return.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,11 @@ test();
7373
--EXPECT--
7474
Cannot add element to the array as the next element is already occupied
7575
Cannot access offset of type array on array
76-
Cannot access offset of type object on array
76+
Cannot access offset of type stdClass on array
7777
Cannot use a scalar value as an array
7878
Cannot add element to the array as the next element is already occupied
7979
Cannot access offset of type array on array
80-
Cannot access offset of type object on array
80+
Cannot access offset of type stdClass on array
8181
Cannot use a scalar value as an array
8282
Attempt to assign property "foo" on true
8383
Attempt to assign property "foo" on true

Zend/tests/bug24773.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Bug #24773 (unset() of integers treated as arrays causes a crash)
66
unset($array["lvl1"]["lvl2"]["b"]);
77
?>
88
--EXPECTF--
9-
Fatal error: Uncaught TypeError: Cannot access offset of type string on string in %s:%d
9+
Fatal error: Uncaught Error: Cannot unset string offsets in %s:%d
1010
Stack trace:
1111
#0 {main}
1212
thrown in %s on line %d

Zend/tests/gh8821.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ new Bravo();
1515

1616
?>
1717
--EXPECTF--
18-
Fatal error: Uncaught TypeError: Cannot access offset of type object on array in %sgh8821.php:8
18+
Fatal error: Uncaught TypeError: Cannot access offset of type Alpha on array in %sgh8821.php:8
1919
Stack trace:
2020
#0 %sgh8821.php(11): [constant expression]()
2121
#1 {main}

Zend/tests/illegal_offset_unset_isset_empty.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,6 @@ try {
2222

2323
?>
2424
--EXPECT--
25-
Cannot access offset of type array in unset
25+
Cannot unset offset of type array on array
2626
Cannot access offset of type array in isset or empty
2727
Cannot access offset of type array in isset or empty

Zend/tests/init_array_illegal_offset_type.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@ try {
1212
}
1313
?>
1414
--EXPECT--
15-
Cannot access offset of type object on array
15+
Cannot access offset of type stdClass on array

Zend/tests/isset_array.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,4 @@ bool(false)
4747
Warning: Resource ID#%d used as offset, casting to integer (%d) in %s on line %d
4848
bool(false)
4949
Cannot access offset of type array in isset or empty
50-
Cannot access offset of type object in isset or empty
50+
Cannot access offset of type stdClass in isset or empty

Zend/tests/offset_array.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,6 @@ int(1)
4848

4949
Warning: Resource ID#%d used as offset, casting to integer (%d) in %s on line %d
5050
int(%d)
51-
Cannot access offset of type object on array
51+
Cannot access offset of type stdClass on array
5252
Cannot access offset of type array on array
5353
Done

Zend/zend.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1719,6 +1719,29 @@ ZEND_API ZEND_COLD void zend_throw_error(zend_class_entry *exception_ce, const c
17191719
}
17201720
/* }}} */
17211721

1722+
/* type should be one of the BP_VAR_* constants, only special messages happen for isset/empty and unset */
1723+
ZEND_API ZEND_COLD void zend_illegal_container_offset(const zend_string *container, const zval *offset, int type)
1724+
{
1725+
switch (type) {
1726+
case BP_VAR_IS:
1727+
zend_type_error("Cannot access offset of type %s in isset or empty",
1728+
zend_zval_type_name(offset));
1729+
return;
1730+
case BP_VAR_UNSET:
1731+
/* Consistent error for when trying to unset a string offset */
1732+
if (zend_string_equals(container, ZSTR_KNOWN(ZEND_STR_STRING))) {
1733+
zend_throw_error(NULL, "Cannot unset string offsets");
1734+
} else {
1735+
zend_type_error("Cannot unset offset of type %s on %s", zend_zval_type_name(offset), ZSTR_VAL(container));
1736+
}
1737+
return;
1738+
default:
1739+
zend_type_error("Cannot access offset of type %s on %s",
1740+
zend_zval_type_name(offset), ZSTR_VAL(container));
1741+
return;
1742+
}
1743+
}
1744+
17221745
ZEND_API ZEND_COLD void zend_type_error(const char *format, ...) /* {{{ */
17231746
{
17241747
va_list va;

Zend/zend.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,8 @@ ZEND_API ZEND_COLD void zend_throw_error(zend_class_entry *exception_ce, const c
357357
ZEND_API ZEND_COLD void zend_type_error(const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 1, 2);
358358
ZEND_API ZEND_COLD void zend_argument_count_error(const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 1, 2);
359359
ZEND_API ZEND_COLD void zend_value_error(const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 1, 2);
360+
/* type should be one of the BP_VAR_* constants, only special messages happen for isset/empty and unset */
361+
ZEND_API ZEND_COLD void zend_illegal_container_offset(const zend_string *container, const zval *offset, int type);
360362

361363
ZEND_COLD void zenderror(const char *error);
362364

Zend/zend_API.c

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -407,16 +407,6 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_argument_error_variadic(zend_class_en
407407
}
408408
/* }}} */
409409

410-
ZEND_API ZEND_COLD void zend_illegal_array_offset(const zval *offset)
411-
{
412-
zend_type_error("Cannot access offset of type %s on array", zend_get_type_by_const(Z_TYPE_P(offset)));
413-
}
414-
415-
ZEND_API ZEND_COLD void zend_illegal_empty_or_isset_offset(const zval *offset)
416-
{
417-
zend_type_error("Cannot access offset of type %s in isset or empty", zend_get_type_by_const(Z_TYPE_P(offset)));
418-
}
419-
420410
ZEND_API ZEND_COLD void zend_argument_error(zend_class_entry *error_ce, uint32_t arg_num, const char *format, ...) /* {{{ */
421411
{
422412
va_list va;
@@ -2112,7 +2102,7 @@ ZEND_API zend_result array_set_zval_key(HashTable *ht, zval *key, zval *value) /
21122102
result = zend_hash_index_update(ht, zend_dval_to_lval_safe(Z_DVAL_P(key)), value);
21132103
break;
21142104
default:
2115-
zend_illegal_array_offset(key);
2105+
zend_illegal_container_offset(ZSTR_KNOWN(ZEND_STR_ARRAY), key, BP_VAR_W);
21162106
result = NULL;
21172107
}
21182108

Zend/zend_execute.c

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1506,24 +1506,24 @@ static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_use_object_as_array(v
15061506
zend_throw_error(NULL, "Cannot use object as array");
15071507
}
15081508

1509-
static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_illegal_unset_offset(const zval *offset)
1509+
static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_illegal_array_offset_access(const zval *offset)
15101510
{
1511-
zend_type_error("Cannot access offset of type %s in unset", zend_get_type_by_const(Z_TYPE_P(offset)));
1511+
zend_illegal_container_offset(ZSTR_KNOWN(ZEND_STR_ARRAY), offset, BP_VAR_RW);
15121512
}
15131513

1514-
static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_illegal_array_offset(const zval *offset)
1514+
static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_illegal_array_offset_isset(const zval *offset)
15151515
{
1516-
zend_type_error("Cannot access offset of type %s on array", zend_get_type_by_const(Z_TYPE_P(offset)));
1516+
zend_illegal_container_offset(ZSTR_KNOWN(ZEND_STR_ARRAY), offset, BP_VAR_IS);
15171517
}
15181518

1519-
static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_illegal_empty_or_isset_offset(const zval *offset)
1519+
static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_illegal_array_offset_unset(const zval *offset)
15201520
{
1521-
zend_type_error("Cannot access offset of type %s in isset or empty", zend_get_type_by_const(Z_TYPE_P(offset)));
1521+
zend_illegal_container_offset(ZSTR_KNOWN(ZEND_STR_ARRAY), offset, BP_VAR_UNSET);
15221522
}
15231523

1524-
static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_illegal_string_offset(const zval *offset)
1524+
static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_illegal_string_offset(const zval *offset, int type)
15251525
{
1526-
zend_type_error("Cannot access offset of type %s on string", zend_zval_type_name(offset));
1526+
zend_illegal_container_offset(ZSTR_KNOWN(ZEND_STR_STRING), offset, type);
15271527
}
15281528

15291529
static zend_never_inline void zend_assign_to_object_dim(zend_object *obj, zval *dim, zval *value OPLINE_DC EXECUTE_DATA_DC)
@@ -1651,7 +1651,7 @@ static zend_never_inline zend_long zend_check_string_offset(zval *dim, int type
16511651
}
16521652
return offset;
16531653
}
1654-
zend_illegal_string_offset(dim);
1654+
zend_illegal_string_offset(dim, type);
16551655
return 0;
16561656
}
16571657
case IS_UNDEF:
@@ -1667,7 +1667,7 @@ static zend_never_inline zend_long zend_check_string_offset(zval *dim, int type
16671667
dim = Z_REFVAL_P(dim);
16681668
goto try_again;
16691669
default:
1670-
zend_illegal_string_offset(dim);
1670+
zend_illegal_string_offset(dim, type);
16711671
return 0;
16721672
}
16731673

@@ -2390,7 +2390,7 @@ static zend_never_inline uint8_t slow_index_convert(HashTable *ht, const zval *d
23902390
value->lval = 1;
23912391
return IS_LONG;
23922392
default:
2393-
zend_illegal_array_offset(dim);
2393+
zend_illegal_array_offset_access(dim);
23942394
return IS_NULL;
23952395
}
23962396
}
@@ -2464,7 +2464,7 @@ static zend_never_inline uint8_t slow_index_convert_w(HashTable *ht, const zval
24642464
value->lval = 1;
24652465
return IS_LONG;
24662466
default:
2467-
zend_illegal_array_offset(dim);
2467+
zend_illegal_array_offset_access(dim);
24682468
return IS_NULL;
24692469
}
24702470
}
@@ -2762,7 +2762,7 @@ static zend_always_inline void zend_fetch_dimension_address_read(zval *result, z
27622762
ZVAL_NULL(result);
27632763
return;
27642764
}
2765-
zend_illegal_string_offset(dim);
2765+
zend_illegal_string_offset(dim, BP_VAR_R);
27662766
ZVAL_NULL(result);
27672767
return;
27682768
}
@@ -2801,7 +2801,7 @@ static zend_always_inline void zend_fetch_dimension_address_read(zval *result, z
28012801
dim = Z_REFVAL_P(dim);
28022802
goto try_string_offset;
28032803
default:
2804-
zend_illegal_string_offset(dim);
2804+
zend_illegal_string_offset(dim, BP_VAR_R);
28052805
ZVAL_NULL(result);
28062806
return;
28072807
}
@@ -2923,7 +2923,7 @@ static zend_never_inline zval* ZEND_FASTCALL zend_find_array_dim_slow(HashTable
29232923
ZVAL_UNDEFINED_OP2();
29242924
goto str_idx;
29252925
} else {
2926-
zend_illegal_empty_or_isset_offset(offset);
2926+
zend_illegal_array_offset_isset(offset);
29272927
return NULL;
29282928
}
29292929
}
@@ -3046,7 +3046,7 @@ static zend_never_inline bool ZEND_FASTCALL zend_array_key_exists_fast(HashTable
30463046
str = ZSTR_EMPTY_ALLOC();
30473047
goto str_key;
30483048
} else {
3049-
zend_illegal_array_offset(key);
3049+
zend_illegal_array_offset_access(key);
30503050
return 0;
30513051
}
30523052
}

Zend/zend_vm_def.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6098,7 +6098,7 @@ ZEND_VM_C_LABEL(num_index):
60986098
str = ZSTR_EMPTY_ALLOC();
60996099
ZEND_VM_C_GOTO(str_index);
61006100
} else {
6101-
zend_illegal_array_offset(offset);
6101+
zend_illegal_array_offset_access(offset);
61026102
zval_ptr_dtor_nogc(expr_ptr);
61036103
}
61046104
FREE_OP2();
@@ -6610,7 +6610,7 @@ ZEND_VM_C_LABEL(num_index_dim):
66106610
key = ZSTR_EMPTY_ALLOC();
66116611
ZEND_VM_C_GOTO(str_index_dim);
66126612
} else {
6613-
zend_illegal_unset_offset(offset);
6613+
zend_illegal_array_offset_unset(offset);
66146614
}
66156615
break;
66166616
} else if (Z_ISREF_P(container)) {

0 commit comments

Comments
 (0)