Skip to content

Commit a6c9c7c

Browse files
committed
Handle resources used as array keys consistently
Resources used as array keys are generally handled by throwing a notice and converting the resource to the resource handle. The only exception is the [$resource => null] syntax, where this was treated as an illegal offset type instead. However, this also only happened for VM evaluations, the AST evaluator did handle resources correctly.
1 parent d71f859 commit a6c9c7c

10 files changed

+147
-41
lines changed

Zend/zend_vm_def.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5717,6 +5717,10 @@ ZEND_VM_C_LABEL(num_index):
57175717
} else if (Z_TYPE_P(offset) == IS_TRUE) {
57185718
hval = 1;
57195719
ZEND_VM_C_GOTO(num_index);
5720+
} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
5721+
zend_use_resource_as_offset(offset);
5722+
hval = Z_RES_HANDLE_P(offset);
5723+
ZEND_VM_C_GOTO(num_index);
57205724
} else if (OP2_TYPE == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
57215725
ZVAL_UNDEFINED_OP2();
57225726
str = ZSTR_EMPTY_ALLOC();

Zend/zend_vm_execute.h

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6169,6 +6169,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_C
61696169
} else if (Z_TYPE_P(offset) == IS_TRUE) {
61706170
hval = 1;
61716171
goto num_index;
6172+
} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
6173+
zend_use_resource_as_offset(offset);
6174+
hval = Z_RES_HANDLE_P(offset);
6175+
goto num_index;
61726176
} else if (IS_CONST == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
61736177
ZVAL_UNDEFINED_OP2();
61746178
str = ZSTR_EMPTY_ALLOC();
@@ -8356,6 +8360,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_T
83568360
} else if (Z_TYPE_P(offset) == IS_TRUE) {
83578361
hval = 1;
83588362
goto num_index;
8363+
} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
8364+
zend_use_resource_as_offset(offset);
8365+
hval = Z_RES_HANDLE_P(offset);
8366+
goto num_index;
83598367
} else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
83608368
ZVAL_UNDEFINED_OP2();
83618369
str = ZSTR_EMPTY_ALLOC();
@@ -9315,6 +9323,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_U
93159323
} else if (Z_TYPE_P(offset) == IS_TRUE) {
93169324
hval = 1;
93179325
goto num_index;
9326+
} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
9327+
zend_use_resource_as_offset(offset);
9328+
hval = Z_RES_HANDLE_P(offset);
9329+
goto num_index;
93189330
} else if (IS_UNUSED == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
93199331
ZVAL_UNDEFINED_OP2();
93209332
str = ZSTR_EMPTY_ALLOC();
@@ -10799,6 +10811,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_C
1079910811
} else if (Z_TYPE_P(offset) == IS_TRUE) {
1080010812
hval = 1;
1080110813
goto num_index;
10814+
} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
10815+
zend_use_resource_as_offset(offset);
10816+
hval = Z_RES_HANDLE_P(offset);
10817+
goto num_index;
1080210818
} else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
1080310819
ZVAL_UNDEFINED_OP2();
1080410820
str = ZSTR_EMPTY_ALLOC();
@@ -18744,6 +18760,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CON
1874418760
} else if (Z_TYPE_P(offset) == IS_TRUE) {
1874518761
hval = 1;
1874618762
goto num_index;
18763+
} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
18764+
zend_use_resource_as_offset(offset);
18765+
hval = Z_RES_HANDLE_P(offset);
18766+
goto num_index;
1874718767
} else if (IS_CONST == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
1874818768
ZVAL_UNDEFINED_OP2();
1874918769
str = ZSTR_EMPTY_ALLOC();
@@ -19168,6 +19188,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP
1916819188
} else if (Z_TYPE_P(offset) == IS_TRUE) {
1916919189
hval = 1;
1917019190
goto num_index;
19191+
} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
19192+
zend_use_resource_as_offset(offset);
19193+
hval = Z_RES_HANDLE_P(offset);
19194+
goto num_index;
1917119195
} else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
1917219196
ZVAL_UNDEFINED_OP2();
1917319197
str = ZSTR_EMPTY_ALLOC();
@@ -19668,6 +19692,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNU
1966819692
} else if (Z_TYPE_P(offset) == IS_TRUE) {
1966919693
hval = 1;
1967019694
goto num_index;
19695+
} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
19696+
zend_use_resource_as_offset(offset);
19697+
hval = Z_RES_HANDLE_P(offset);
19698+
goto num_index;
1967119699
} else if (IS_UNUSED == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
1967219700
ZVAL_UNDEFINED_OP2();
1967319701
str = ZSTR_EMPTY_ALLOC();
@@ -20071,6 +20099,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_
2007120099
} else if (Z_TYPE_P(offset) == IS_TRUE) {
2007220100
hval = 1;
2007320101
goto num_index;
20102+
} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
20103+
zend_use_resource_as_offset(offset);
20104+
hval = Z_RES_HANDLE_P(offset);
20105+
goto num_index;
2007420106
} else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
2007520107
ZVAL_UNDEFINED_OP2();
2007620108
str = ZSTR_EMPTY_ALLOC();
@@ -23897,6 +23929,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CON
2389723929
} else if (Z_TYPE_P(offset) == IS_TRUE) {
2389823930
hval = 1;
2389923931
goto num_index;
23932+
} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
23933+
zend_use_resource_as_offset(offset);
23934+
hval = Z_RES_HANDLE_P(offset);
23935+
goto num_index;
2390023936
} else if (IS_CONST == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
2390123937
ZVAL_UNDEFINED_OP2();
2390223938
str = ZSTR_EMPTY_ALLOC();
@@ -26043,6 +26079,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP
2604326079
} else if (Z_TYPE_P(offset) == IS_TRUE) {
2604426080
hval = 1;
2604526081
goto num_index;
26082+
} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
26083+
zend_use_resource_as_offset(offset);
26084+
hval = Z_RES_HANDLE_P(offset);
26085+
goto num_index;
2604626086
} else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
2604726087
ZVAL_UNDEFINED_OP2();
2604826088
str = ZSTR_EMPTY_ALLOC();
@@ -27656,6 +27696,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNU
2765627696
} else if (Z_TYPE_P(offset) == IS_TRUE) {
2765727697
hval = 1;
2765827698
goto num_index;
27699+
} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
27700+
zend_use_resource_as_offset(offset);
27701+
hval = Z_RES_HANDLE_P(offset);
27702+
goto num_index;
2765927703
} else if (IS_UNUSED == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
2766027704
ZVAL_UNDEFINED_OP2();
2766127705
str = ZSTR_EMPTY_ALLOC();
@@ -29793,6 +29837,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_
2979329837
} else if (Z_TYPE_P(offset) == IS_TRUE) {
2979429838
hval = 1;
2979529839
goto num_index;
29840+
} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
29841+
zend_use_resource_as_offset(offset);
29842+
hval = Z_RES_HANDLE_P(offset);
29843+
goto num_index;
2979629844
} else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
2979729845
ZVAL_UNDEFINED_OP2();
2979829846
str = ZSTR_EMPTY_ALLOC();
@@ -40974,6 +41022,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONS
4097441022
} else if (Z_TYPE_P(offset) == IS_TRUE) {
4097541023
hval = 1;
4097641024
goto num_index;
41025+
} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
41026+
zend_use_resource_as_offset(offset);
41027+
hval = Z_RES_HANDLE_P(offset);
41028+
goto num_index;
4097741029
} else if (IS_CONST == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
4097841030
ZVAL_UNDEFINED_OP2();
4097941031
str = ZSTR_EMPTY_ALLOC();
@@ -44396,6 +44448,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPV
4439644448
} else if (Z_TYPE_P(offset) == IS_TRUE) {
4439744449
hval = 1;
4439844450
goto num_index;
44451+
} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
44452+
zend_use_resource_as_offset(offset);
44453+
hval = Z_RES_HANDLE_P(offset);
44454+
goto num_index;
4439944455
} else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
4440044456
ZVAL_UNDEFINED_OP2();
4440144457
str = ZSTR_EMPTY_ALLOC();
@@ -46129,6 +46185,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUS
4612946185
} else if (Z_TYPE_P(offset) == IS_TRUE) {
4613046186
hval = 1;
4613146187
goto num_index;
46188+
} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
46189+
zend_use_resource_as_offset(offset);
46190+
hval = Z_RES_HANDLE_P(offset);
46191+
goto num_index;
4613246192
} else if (IS_UNUSED == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
4613346193
ZVAL_UNDEFINED_OP2();
4613446194
str = ZSTR_EMPTY_ALLOC();
@@ -49553,6 +49613,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_H
4955349613
} else if (Z_TYPE_P(offset) == IS_TRUE) {
4955449614
hval = 1;
4955549615
goto num_index;
49616+
} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
49617+
zend_use_resource_as_offset(offset);
49618+
hval = Z_RES_HANDLE_P(offset);
49619+
goto num_index;
4955649620
} else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
4955749621
ZVAL_UNDEFINED_OP2();
4955849622
str = ZSTR_EMPTY_ALLOC();

ext/opcache/Optimizer/zend_inference.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3243,7 +3243,7 @@ static int zend_update_type_info(const zend_op_array *op_array,
32433243
if (opline->op2_type == IS_UNUSED) {
32443244
tmp |= MAY_BE_ARRAY_KEY_LONG;
32453245
} else {
3246-
if (t2 & (MAY_BE_LONG|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_DOUBLE)) {
3246+
if (t2 & (MAY_BE_LONG|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_DOUBLE|MAY_BE_RESOURCE)) {
32473247
tmp |= MAY_BE_ARRAY_KEY_LONG;
32483248
}
32493249
if (t2 & (MAY_BE_STRING)) {

ext/standard/tests/array/array_combine_variation4.phpt

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,11 @@ echo "Done";
9292

9393
Warning: Illegal offset type in %s on line %d
9494

95-
Warning: Illegal offset type in %s on line %d
95+
Notice: Resource ID#%d used as offset, casting to integer (%d) in %s on line %d
9696

9797
Warning: Illegal offset type in %s on line %d
9898

99-
Warning: Illegal offset type in %s on line %d
99+
Notice: Resource ID#%d used as offset, casting to integer (%d) in %s on line %d
100100

101101
Warning: Illegal offset type in %s on line %d
102102
-- Iteration 1 --
@@ -169,16 +169,20 @@ array(2) {
169169
string(6) "string"
170170
}
171171
-- Iteration 10 --
172-
array(1) {
172+
array(2) {
173173
["hello"]=>
174174
string(5) "hello"
175+
["resource"]=>
176+
string(8) "resource"
175177
}
176178
-- Iteration 11 --
177-
array(6) {
179+
array(7) {
178180
[1]=>
179181
int(1)
180182
["2.2"]=>
181183
float(2.2)
184+
["resource"]=>
185+
string(8) "resource"
182186
["int"]=>
183187
string(3) "int"
184188
["float"]=>

ext/standard/tests/array/array_map_variation4.phpt

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -79,13 +79,13 @@ echo "Done";
7979
--EXPECTF--
8080
*** Testing array_map() : associative array with diff. keys for 'arr1' argument ***
8181

82-
Warning: Illegal offset type in %s on line %d%d
82+
Warning: Illegal offset type in %s on line %d
8383

84-
Warning: Illegal offset type in %s on line %d%d
84+
Notice: Resource ID#%d used as offset, casting to integer (%d) in %s on line %d
8585

86-
Warning: Illegal offset type in %s on line %d%d
86+
Warning: Illegal offset type in %s on line %d
8787

88-
Warning: Illegal offset type in %s on line %d%d
88+
Notice: Resource ID#%d used as offset, casting to integer (%d) in %s on line %d
8989
-- Iteration 1 --
9090
array(0) {
9191
}
@@ -157,16 +157,20 @@ array(2) {
157157
string(6) "string"
158158
}
159159
-- Iteration 10 --
160-
array(1) {
160+
array(2) {
161161
[""]=>
162162
string(5) "hello"
163+
[5]=>
164+
string(8) "resource"
163165
}
164166
-- Iteration 11 --
165-
array(6) {
167+
array(7) {
166168
["hello"]=>
167169
int(1)
168170
["fruit"]=>
169171
float(2.2)
172+
[5]=>
173+
string(8) "resource"
170174
[133]=>
171175
string(3) "int"
172176
[444]=>

ext/standard/tests/array/array_merge_recursive_variation4.phpt

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ echo "Done";
8282

8383
Warning: Illegal offset type in %s on line %d
8484

85-
Warning: Illegal offset type in %s on line %d
85+
Notice: Resource ID#%d used as offset, casting to integer (%d) in %s on line %d
8686
-- Iteration 1 --
8787
-- With default argument --
8888
array(2) {
@@ -383,31 +383,35 @@ array(7) {
383383
}
384384
-- Iteration 8 --
385385
-- With default argument --
386-
array(3) {
386+
array(4) {
387387
[""]=>
388388
array(1) {
389389
[0]=>
390390
string(5) "unset"
391391
}
392392
[0]=>
393-
int(11)
393+
string(8) "resource"
394394
[1]=>
395+
int(11)
396+
[2]=>
395397
string(5) "hello"
396398
}
397399
-- With more arguments --
398-
array(7) {
400+
array(8) {
399401
[""]=>
400402
array(1) {
401403
[0]=>
402404
string(5) "unset"
403405
}
404406
[0]=>
405-
int(11)
407+
string(8) "resource"
406408
[1]=>
407-
string(5) "hello"
409+
int(11)
408410
[2]=>
409-
string(3) "one"
411+
string(5) "hello"
410412
[3]=>
413+
string(3) "one"
414+
[4]=>
411415
int(2)
412416
["string"]=>
413417
string(5) "hello"

0 commit comments

Comments
 (0)