]> granicus.if.org Git - php/commitdiff
Handle resources used as array keys consistently
authorNikita Popov <nikita.ppv@gmail.com>
Fri, 27 Sep 2019 08:39:21 +0000 (10:39 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Fri, 27 Sep 2019 08:40:41 +0000 (10:40 +0200)
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.

Zend/zend_vm_def.h
Zend/zend_vm_execute.h
ext/opcache/Optimizer/zend_inference.c
ext/standard/tests/array/array_combine_variation4.phpt
ext/standard/tests/array/array_map_variation4.phpt
ext/standard/tests/array/array_merge_recursive_variation4.phpt
ext/standard/tests/array/array_reverse_variation4.phpt
ext/standard/tests/array/array_unique_variation3.phpt
ext/standard/tests/array/array_unshift_variation4.phpt
scripts/dev/bless_tests.php

index 823f5398b28f49dbcfe0640cc567368b0515e5d3..7c102073a3b501f84f460ba22d2312bfcd1e4fd0 100644 (file)
@@ -5717,6 +5717,10 @@ ZEND_VM_C_LABEL(num_index):
                } else if (Z_TYPE_P(offset) == IS_TRUE) {
                        hval = 1;
                        ZEND_VM_C_GOTO(num_index);
+               } else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+                       zend_use_resource_as_offset(offset);
+                       hval = Z_RES_HANDLE_P(offset);
+                       ZEND_VM_C_GOTO(num_index);
                } else if (OP2_TYPE == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
                        ZVAL_UNDEFINED_OP2();
                        str = ZSTR_EMPTY_ALLOC();
index 81b6c3d8e6325b1c59f65d656373d789d6e6847b..4cd21c0e61f58f33bd5833085d5a711839f4cebd 100644 (file)
@@ -6169,6 +6169,10 @@ num_index:
                } else if (Z_TYPE_P(offset) == IS_TRUE) {
                        hval = 1;
                        goto num_index;
+               } else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+                       zend_use_resource_as_offset(offset);
+                       hval = Z_RES_HANDLE_P(offset);
+                       goto num_index;
                } else if (IS_CONST == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
                        ZVAL_UNDEFINED_OP2();
                        str = ZSTR_EMPTY_ALLOC();
@@ -8356,6 +8360,10 @@ num_index:
                } else if (Z_TYPE_P(offset) == IS_TRUE) {
                        hval = 1;
                        goto num_index;
+               } else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+                       zend_use_resource_as_offset(offset);
+                       hval = Z_RES_HANDLE_P(offset);
+                       goto num_index;
                } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
                        ZVAL_UNDEFINED_OP2();
                        str = ZSTR_EMPTY_ALLOC();
@@ -9315,6 +9323,10 @@ num_index:
                } else if (Z_TYPE_P(offset) == IS_TRUE) {
                        hval = 1;
                        goto num_index;
+               } else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+                       zend_use_resource_as_offset(offset);
+                       hval = Z_RES_HANDLE_P(offset);
+                       goto num_index;
                } else if (IS_UNUSED == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
                        ZVAL_UNDEFINED_OP2();
                        str = ZSTR_EMPTY_ALLOC();
@@ -10799,6 +10811,10 @@ num_index:
                } else if (Z_TYPE_P(offset) == IS_TRUE) {
                        hval = 1;
                        goto num_index;
+               } else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+                       zend_use_resource_as_offset(offset);
+                       hval = Z_RES_HANDLE_P(offset);
+                       goto num_index;
                } else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
                        ZVAL_UNDEFINED_OP2();
                        str = ZSTR_EMPTY_ALLOC();
@@ -18744,6 +18760,10 @@ num_index:
                } else if (Z_TYPE_P(offset) == IS_TRUE) {
                        hval = 1;
                        goto num_index;
+               } else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+                       zend_use_resource_as_offset(offset);
+                       hval = Z_RES_HANDLE_P(offset);
+                       goto num_index;
                } else if (IS_CONST == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
                        ZVAL_UNDEFINED_OP2();
                        str = ZSTR_EMPTY_ALLOC();
@@ -19168,6 +19188,10 @@ num_index:
                } else if (Z_TYPE_P(offset) == IS_TRUE) {
                        hval = 1;
                        goto num_index;
+               } else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+                       zend_use_resource_as_offset(offset);
+                       hval = Z_RES_HANDLE_P(offset);
+                       goto num_index;
                } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
                        ZVAL_UNDEFINED_OP2();
                        str = ZSTR_EMPTY_ALLOC();
@@ -19668,6 +19692,10 @@ num_index:
                } else if (Z_TYPE_P(offset) == IS_TRUE) {
                        hval = 1;
                        goto num_index;
+               } else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+                       zend_use_resource_as_offset(offset);
+                       hval = Z_RES_HANDLE_P(offset);
+                       goto num_index;
                } else if (IS_UNUSED == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
                        ZVAL_UNDEFINED_OP2();
                        str = ZSTR_EMPTY_ALLOC();
@@ -20071,6 +20099,10 @@ num_index:
                } else if (Z_TYPE_P(offset) == IS_TRUE) {
                        hval = 1;
                        goto num_index;
+               } else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+                       zend_use_resource_as_offset(offset);
+                       hval = Z_RES_HANDLE_P(offset);
+                       goto num_index;
                } else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
                        ZVAL_UNDEFINED_OP2();
                        str = ZSTR_EMPTY_ALLOC();
@@ -23897,6 +23929,10 @@ num_index:
                } else if (Z_TYPE_P(offset) == IS_TRUE) {
                        hval = 1;
                        goto num_index;
+               } else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+                       zend_use_resource_as_offset(offset);
+                       hval = Z_RES_HANDLE_P(offset);
+                       goto num_index;
                } else if (IS_CONST == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
                        ZVAL_UNDEFINED_OP2();
                        str = ZSTR_EMPTY_ALLOC();
@@ -26043,6 +26079,10 @@ num_index:
                } else if (Z_TYPE_P(offset) == IS_TRUE) {
                        hval = 1;
                        goto num_index;
+               } else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+                       zend_use_resource_as_offset(offset);
+                       hval = Z_RES_HANDLE_P(offset);
+                       goto num_index;
                } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
                        ZVAL_UNDEFINED_OP2();
                        str = ZSTR_EMPTY_ALLOC();
@@ -27656,6 +27696,10 @@ num_index:
                } else if (Z_TYPE_P(offset) == IS_TRUE) {
                        hval = 1;
                        goto num_index;
+               } else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+                       zend_use_resource_as_offset(offset);
+                       hval = Z_RES_HANDLE_P(offset);
+                       goto num_index;
                } else if (IS_UNUSED == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
                        ZVAL_UNDEFINED_OP2();
                        str = ZSTR_EMPTY_ALLOC();
@@ -29793,6 +29837,10 @@ num_index:
                } else if (Z_TYPE_P(offset) == IS_TRUE) {
                        hval = 1;
                        goto num_index;
+               } else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+                       zend_use_resource_as_offset(offset);
+                       hval = Z_RES_HANDLE_P(offset);
+                       goto num_index;
                } else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
                        ZVAL_UNDEFINED_OP2();
                        str = ZSTR_EMPTY_ALLOC();
@@ -40974,6 +41022,10 @@ num_index:
                } else if (Z_TYPE_P(offset) == IS_TRUE) {
                        hval = 1;
                        goto num_index;
+               } else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+                       zend_use_resource_as_offset(offset);
+                       hval = Z_RES_HANDLE_P(offset);
+                       goto num_index;
                } else if (IS_CONST == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
                        ZVAL_UNDEFINED_OP2();
                        str = ZSTR_EMPTY_ALLOC();
@@ -44396,6 +44448,10 @@ num_index:
                } else if (Z_TYPE_P(offset) == IS_TRUE) {
                        hval = 1;
                        goto num_index;
+               } else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+                       zend_use_resource_as_offset(offset);
+                       hval = Z_RES_HANDLE_P(offset);
+                       goto num_index;
                } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
                        ZVAL_UNDEFINED_OP2();
                        str = ZSTR_EMPTY_ALLOC();
@@ -46129,6 +46185,10 @@ num_index:
                } else if (Z_TYPE_P(offset) == IS_TRUE) {
                        hval = 1;
                        goto num_index;
+               } else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+                       zend_use_resource_as_offset(offset);
+                       hval = Z_RES_HANDLE_P(offset);
+                       goto num_index;
                } else if (IS_UNUSED == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
                        ZVAL_UNDEFINED_OP2();
                        str = ZSTR_EMPTY_ALLOC();
@@ -49553,6 +49613,10 @@ num_index:
                } else if (Z_TYPE_P(offset) == IS_TRUE) {
                        hval = 1;
                        goto num_index;
+               } else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+                       zend_use_resource_as_offset(offset);
+                       hval = Z_RES_HANDLE_P(offset);
+                       goto num_index;
                } else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
                        ZVAL_UNDEFINED_OP2();
                        str = ZSTR_EMPTY_ALLOC();
index 43961a6158b451a64c7c4a0279cbc447ce6cec62..f89b133b9267aefeb59637aac4917174111f2e1d 100644 (file)
@@ -3243,7 +3243,7 @@ static int zend_update_type_info(const zend_op_array *op_array,
                                        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)) {
+                                               if (t2 & (MAY_BE_LONG|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_DOUBLE|MAY_BE_RESOURCE)) {
                                                        tmp |= MAY_BE_ARRAY_KEY_LONG;
                                                }
                                                if (t2 & (MAY_BE_STRING)) {
index dd3187a1f04898b1033df5f6ec75e876845194c4..a7ea0a9dc4768d0fee0065c53b6cde43108d8fe0 100644 (file)
@@ -92,11 +92,11 @@ echo "Done";
 
 Warning: Illegal offset type in %s on line %d
 
-Warning: Illegal offset type in %s on line %d
+Notice: Resource ID#%d used as offset, casting to integer (%d) in %s on line %d
 
 Warning: Illegal offset type in %s on line %d
 
-Warning: Illegal offset type in %s on line %d
+Notice: Resource ID#%d used as offset, casting to integer (%d) in %s on line %d
 
 Warning: Illegal offset type in %s on line %d
 -- Iteration 1 --
@@ -169,16 +169,20 @@ array(2) {
   string(6) "string"
 }
 -- Iteration 10 --
-array(1) {
+array(2) {
   ["hello"]=>
   string(5) "hello"
+  ["resource"]=>
+  string(8) "resource"
 }
 -- Iteration 11 --
-array(6) {
+array(7) {
   [1]=>
   int(1)
   ["2.2"]=>
   float(2.2)
+  ["resource"]=>
+  string(8) "resource"
   ["int"]=>
   string(3) "int"
   ["float"]=>
index d99a529e3a70fcbdf50904031af53ab0d652456a..e5b4c062c1094d1451b310c4b04b4000c9f16af3 100644 (file)
@@ -79,13 +79,13 @@ echo "Done";
 --EXPECTF--
 *** Testing array_map() : associative array with diff. keys for 'arr1' argument ***
 
-Warning: Illegal offset type in %s on line %d%d
+Warning: Illegal offset type in %s on line %d
 
-Warning: Illegal offset type in %s on line %d%d
+Notice: Resource ID#%d used as offset, casting to integer (%d) in %s on line %d
 
-Warning: Illegal offset type in %s on line %d%d
+Warning: Illegal offset type in %s on line %d
 
-Warning: Illegal offset type in %s on line %d%d
+Notice: Resource ID#%d used as offset, casting to integer (%d) in %s on line %d
 -- Iteration 1 --
 array(0) {
 }
@@ -157,16 +157,20 @@ array(2) {
   string(6) "string"
 }
 -- Iteration 10 --
-array(1) {
+array(2) {
   [""]=>
   string(5) "hello"
+  [5]=>
+  string(8) "resource"
 }
 -- Iteration 11 --
-array(6) {
+array(7) {
   ["hello"]=>
   int(1)
   ["fruit"]=>
   float(2.2)
+  [5]=>
+  string(8) "resource"
   [133]=>
   string(3) "int"
   [444]=>
index f73dd9c628675a20a56abf0ff50751c78dafd566..f2c1e82a0cf7b303f4fe1930489e38ea598a5646 100644 (file)
@@ -82,7 +82,7 @@ echo "Done";
 
 Warning: Illegal offset type in %s on line %d
 
-Warning: Illegal offset type in %s on line %d
+Notice: Resource ID#%d used as offset, casting to integer (%d) in %s on line %d
 -- Iteration 1 --
 -- With default argument --
 array(2) {
@@ -383,31 +383,35 @@ array(7) {
 }
 -- Iteration 8 --
 -- With default argument --
-array(3) {
+array(4) {
   [""]=>
   array(1) {
     [0]=>
     string(5) "unset"
   }
   [0]=>
-  int(11)
+  string(8) "resource"
   [1]=>
+  int(11)
+  [2]=>
   string(5) "hello"
 }
 -- With more arguments --
-array(7) {
+array(8) {
   [""]=>
   array(1) {
     [0]=>
     string(5) "unset"
   }
   [0]=>
-  int(11)
+  string(8) "resource"
   [1]=>
-  string(5) "hello"
+  int(11)
   [2]=>
-  string(3) "one"
+  string(5) "hello"
   [3]=>
+  string(3) "one"
+  [4]=>
   int(2)
   ["string"]=>
   string(5) "hello"
index 88f36ea025749f428ee82d672aab79af0ac1c65e..09b2eb4beec95ce393b93ddf3991494a1dfdb903 100644 (file)
@@ -85,11 +85,11 @@ echo "Done";
 
 Warning: Illegal offset type in %s on line %d
 
-Warning: Illegal offset type in %s on line %d
+Notice: Resource ID#%d used as offset, casting to integer (%d) in %s on line %d
 
 Warning: Illegal offset type in %s on line %d
 
-Warning: Illegal offset type in %s on line %d
+Notice: Resource ID#%d used as offset, casting to integer (%d) in %s on line %d
 -- Iteration 1 --
 - default argument -
 array(0) {
@@ -314,23 +314,29 @@ array(2) {
 }
 -- Iteration 10 --
 - default argument -
-array(1) {
+array(2) {
+  [0]=>
+  string(8) "resource"
   [""]=>
   string(5) "hello"
 }
 - $preserve keys = true -
-array(1) {
+array(2) {
+  [5]=>
+  string(8) "resource"
   [""]=>
   string(5) "hello"
 }
 - $preserve_keys = false -
-array(1) {
+array(2) {
+  [0]=>
+  string(8) "resource"
   [""]=>
   string(5) "hello"
 }
 -- Iteration 11 --
 - default argument -
-array(6) {
+array(7) {
   ["Hello world"]=>
   string(7) "heredoc"
   [""]=>
@@ -339,13 +345,15 @@ array(6) {
   string(5) "float"
   [1]=>
   string(3) "int"
+  [2]=>
+  string(8) "resource"
   ["fruit"]=>
   float(2.2)
   ["hello"]=>
   int(1)
 }
 - $preserve keys = true -
-array(6) {
+array(7) {
   ["Hello world"]=>
   string(7) "heredoc"
   [""]=>
@@ -354,13 +362,15 @@ array(6) {
   string(5) "float"
   [133]=>
   string(3) "int"
+  [5]=>
+  string(8) "resource"
   ["fruit"]=>
   float(2.2)
   ["hello"]=>
   int(1)
 }
 - $preserve_keys = false -
-array(6) {
+array(7) {
   ["Hello world"]=>
   string(7) "heredoc"
   [""]=>
@@ -369,6 +379,8 @@ array(6) {
   string(5) "float"
   [1]=>
   string(3) "int"
+  [2]=>
+  string(8) "resource"
   ["fruit"]=>
   float(2.2)
   ["hello"]=>
index 95cd1887d1d246218185f449a309038e18c5fb83..205bc3a576c5f048524dafb7893c49ecc7ebb533 100644 (file)
@@ -70,7 +70,7 @@ echo "Done";
 
 Warning: Illegal offset type in %s on line %d
 
-Warning: Illegal offset type in %s on line %d
+Notice: Resource ID#%d used as offset, casting to integer (%d) in %s on line %d
 -- Iteration 1 --
 array(1) {
   [0]=>
@@ -125,10 +125,12 @@ array(2) {
   string(6) "string"
 }
 -- Iteration 8 --
-array(2) {
+array(3) {
   [""]=>
   string(5) "hello"
-  [0]=>
+  [5]=>
+  string(8) "resource"
+  [6]=>
   int(11)
 }
 Done
index 64bf3a8d8245933dfec5070ef62c8ce701eb891f..7f507c98d0e980206f15f7b864873bd5da2d58a5 100644 (file)
@@ -103,11 +103,11 @@ echo "Done";
 
 Warning: Illegal offset type in %s on line %d
 
-Warning: Illegal offset type in %s on line %d
+Notice: Resource ID#%d used as offset, casting to integer (%d) in %s on line %d
 
 Warning: Illegal offset type in %s on line %d
 
-Warning: Illegal offset type in %s on line %d
+Notice: Resource ID#%d used as offset, casting to integer (%d) in %s on line %d
 -- Iteration 1 --
 int(1)
 array(1) {
@@ -330,15 +330,17 @@ array(5) {
   string(6) "string"
 }
 -- Iteration 10 --
-int(2)
-array(2) {
+int(3)
+array(3) {
   [0]=>
   int(10)
   [""]=>
   string(5) "hello"
+  [1]=>
+  string(8) "resource"
 }
-int(4)
-array(4) {
+int(5)
+array(5) {
   [0]=>
   int(10)
   [1]=>
@@ -347,10 +349,12 @@ array(4) {
   string(5) "world"
   [""]=>
   string(5) "hello"
+  [3]=>
+  string(8) "resource"
 }
 -- Iteration 11 --
-int(7)
-array(7) {
+int(8)
+array(8) {
   [0]=>
   int(10)
   ["hello"]=>
@@ -358,16 +362,18 @@ array(7) {
   ["fruit"]=>
   float(2.2)
   [1]=>
-  string(3) "int"
+  string(8) "resource"
   [2]=>
+  string(3) "int"
+  [3]=>
   string(5) "float"
   [""]=>
   string(5) "unset"
   ["Hello world"]=>
   string(7) "heredoc"
 }
-int(9)
-array(9) {
+int(10)
+array(10) {
   [0]=>
   int(10)
   [1]=>
@@ -379,8 +385,10 @@ array(9) {
   ["fruit"]=>
   float(2.2)
   [3]=>
-  string(3) "int"
+  string(8) "resource"
   [4]=>
+  string(3) "int"
+  [5]=>
   string(5) "float"
   [""]=>
   string(5) "unset"
index 25a4843c073651ed5ebe332a4949926094685ced..fbbfe505c9bf124933ea90afbde27cb41c9e77cc 100755 (executable)
@@ -54,6 +54,10 @@ function normalizeOutput(string $out): string {
     $out = preg_replace('/^#(\d+) \/.+\(\d+\):/m', '#$1 %s(%d):', $out);
     $out = preg_replace('/Resource id #\d+/', 'Resource id #%d', $out);
     $out = preg_replace('/resource\(\d+\) of type/', 'resource(%d) of type', $out);
+    $out = preg_replace(
+        '/Resource ID#\d+ used as offset, casting to integer \(\d+\)/',
+        'Resource ID#%d used as offset, casting to integer (%d)',
+        $out);
     $out = preg_replace('/string\(\d+\) "([^"]*%d)/', 'string(%d) "$1', $out);
     return $out;
 }