summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--Zend/tests/const_array_with_resource_key.phpt2
-rw-r--r--Zend/tests/isset_003.phpt2
-rw-r--r--Zend/tests/isset_array.phpt48
-rw-r--r--Zend/zend_API.c2
-rw-r--r--Zend/zend_ast.c4
-rw-r--r--Zend/zend_execute.c16
-rw-r--r--ext/opcache/jit/zend_jit_helpers.c2
-rw-r--r--ext/spl/spl_array.c2
-rw-r--r--ext/spl/tests/bug62978.phpt2
-rw-r--r--ext/standard/array.c23
-rwxr-xr-xext/standard/basic_functions.stub.php9
-rwxr-xr-xext/standard/basic_functions_arginfo.h2
-rw-r--r--ext/standard/tests/array/array_key_exists.phpt15
-rw-r--r--ext/standard/tests/array/array_key_exists_variation1.phpt50
-rw-r--r--ext/standard/tests/array/array_key_exists_variation3.phpt18
16 files changed, 128 insertions, 72 deletions
diff --git a/.gitignore b/.gitignore
index df0fc80a5c..587f4abc42 100644
--- a/.gitignore
+++ b/.gitignore
@@ -247,6 +247,9 @@ php
# Test results generated by `./run-tests.php`
php_test_results_*.txt
+# Temporary test information generated by `./run-tests.php`
+/run-test-info.php
+
# Temporary POST data placeholder files generated by `./run-tests.php`
phpt.*
diff --git a/Zend/tests/const_array_with_resource_key.phpt b/Zend/tests/const_array_with_resource_key.phpt
index 0bf546af50..1e3dee4734 100644
--- a/Zend/tests/const_array_with_resource_key.phpt
+++ b/Zend/tests/const_array_with_resource_key.phpt
@@ -8,7 +8,7 @@ var_dump(FOO);
?>
--EXPECTF--
-Notice: Resource ID#%d used as offset, casting to integer (%d) in %s on line %d
+Warning: Resource ID#%d used as offset, casting to integer (%d) in %s on line %d
array(1) {
[%d]=>
int(42)
diff --git a/Zend/tests/isset_003.phpt b/Zend/tests/isset_003.phpt
index c80a174daf..7b29c1e6b8 100644
--- a/Zend/tests/isset_003.phpt
+++ b/Zend/tests/isset_003.phpt
@@ -1,5 +1,5 @@
--TEST--
-Testing isset accessing undefined array itens and properties
+Testing isset accessing undefined array items and properties
--FILE--
<?php
diff --git a/Zend/tests/isset_array.phpt b/Zend/tests/isset_array.phpt
new file mode 100644
index 0000000000..c7c1876410
--- /dev/null
+++ b/Zend/tests/isset_array.phpt
@@ -0,0 +1,48 @@
+--TEST--
+Using isset() with arrays
+--FILE--
+<?php
+
+$array = [
+ 0 => true,
+ "a" => true,
+];
+
+var_dump(isset($array[0]));
+
+var_dump(isset($array["a"]));
+
+var_dump(isset($array[false]));
+
+var_dump(isset($array[0.6]));
+
+var_dump(isset($array[true]));
+
+var_dump(isset($array[null]));
+
+var_dump(isset($array[STDIN]));
+
+try {
+ isset($array[[]]);
+} catch (TypeError $exception) {
+ echo $exception->getMessage() . "\n";
+}
+
+try {
+ isset($array[new stdClass()]);
+} catch (TypeError $exception) {
+ echo $exception->getMessage() . "\n";
+}
+?>
+--EXPECTF--
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(false)
+bool(false)
+
+Warning: Resource ID#%d used as offset, casting to integer (%d) in %s on line %d
+bool(false)
+Illegal offset type in isset or empty
+Illegal offset type in isset or empty
diff --git a/Zend/zend_API.c b/Zend/zend_API.c
index 5781a95bfd..387f6e1a98 100644
--- a/Zend/zend_API.c
+++ b/Zend/zend_API.c
@@ -1531,7 +1531,7 @@ ZEND_API int array_set_zval_key(HashTable *ht, zval *key, zval *value) /* {{{ */
result = zend_symtable_update(ht, ZSTR_EMPTY_ALLOC(), value);
break;
case IS_RESOURCE:
- zend_error(E_NOTICE, "Resource ID#%d used as offset, casting to integer (%d)", Z_RES_HANDLE_P(key), Z_RES_HANDLE_P(key));
+ zend_error(E_WARNING, "Resource ID#%d used as offset, casting to integer (%d)", Z_RES_HANDLE_P(key), Z_RES_HANDLE_P(key));
result = zend_hash_index_update(ht, Z_RES_HANDLE_P(key), value);
break;
case IS_FALSE:
diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c
index 660e6d5b6f..f0b524b30e 100644
--- a/Zend/zend_ast.c
+++ b/Zend/zend_ast.c
@@ -436,7 +436,7 @@ static int zend_ast_add_array_element(zval *result, zval *offset, zval *expr)
zend_hash_index_update(Z_ARRVAL_P(result), zend_dval_to_lval(Z_DVAL_P(offset)), expr);
break;
case IS_RESOURCE:
- zend_error(E_NOTICE, "Resource ID#%d used as offset, casting to integer (%d)", Z_RES_HANDLE_P(offset), Z_RES_HANDLE_P(offset));
+ zend_error(E_WARNING, "Resource ID#%d used as offset, casting to integer (%d)", Z_RES_HANDLE_P(offset), Z_RES_HANDLE_P(offset));
zend_hash_index_update(Z_ARRVAL_P(result), Z_RES_HANDLE_P(offset), expr);
break;
default:
@@ -451,7 +451,7 @@ static int zend_ast_add_unpacked_element(zval *result, zval *expr) {
HashTable *ht = Z_ARRVAL_P(expr);
zval *val;
zend_string *key;
-
+
ZEND_HASH_FOREACH_STR_KEY_VAL(ht, key, val) {
if (key) {
zend_throw_error(NULL, "Cannot unpack array with string keys");
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index 345335b708..8278f698cd 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -2369,6 +2369,7 @@ str_idx:
hval = 1;
goto num_idx;
} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+ zend_use_resource_as_offset(offset);
hval = Z_RES_HANDLE_P(offset);
goto num_idx;
} else if (/*OP2_TYPE == IS_CV &&*/ Z_TYPE_P(offset) == IS_UNDEF) {
@@ -2478,6 +2479,19 @@ num_key:
} else if (EXPECTED(Z_ISREF_P(key))) {
key = Z_REFVAL_P(key);
goto try_again;
+ } else if (Z_TYPE_P(key) == IS_DOUBLE) {
+ hval = zend_dval_to_lval(Z_DVAL_P(key));
+ goto num_key;
+ } else if (Z_TYPE_P(key) == IS_FALSE) {
+ hval = 0;
+ goto num_key;
+ } else if (Z_TYPE_P(key) == IS_TRUE) {
+ hval = 1;
+ goto num_key;
+ } else if (Z_TYPE_P(key) == IS_RESOURCE) {
+ zend_use_resource_as_offset(key);
+ hval = Z_RES_HANDLE_P(key);
+ goto num_key;
} else if (Z_TYPE_P(key) <= IS_NULL) {
if (UNEXPECTED(Z_TYPE_P(key) == IS_UNDEF)) {
ZVAL_UNDEFINED_OP1();
@@ -2485,7 +2499,7 @@ num_key:
str = ZSTR_EMPTY_ALLOC();
goto str_key;
} else {
- zend_error(E_WARNING, "array_key_exists(): The first argument should be either a string or an integer");
+ zend_type_error("Illegal offset type");
return 0;
}
}
diff --git a/ext/opcache/jit/zend_jit_helpers.c b/ext/opcache/jit/zend_jit_helpers.c
index da96660a10..f581841aab 100644
--- a/ext/opcache/jit/zend_jit_helpers.c
+++ b/ext/opcache/jit/zend_jit_helpers.c
@@ -400,7 +400,7 @@ static int ZEND_FASTCALL zend_jit_fetch_dim_isset_helper(zend_array *ht, zval *d
hval = zend_dval_to_lval(Z_DVAL_P(dim));
goto num_index;
case IS_RESOURCE:
- //zend_error(E_WARNING, "Resource ID#%d used as offset, casting to integer (%d)", Z_RES_HANDLE_P(dim), Z_RES_HANDLE_P(dim));
+ zend_error(E_WARNING, "Resource ID#%d used as offset, casting to integer (%d)", Z_RES_HANDLE_P(dim), Z_RES_HANDLE_P(dim));
hval = Z_RES_HANDLE_P(dim);
goto num_index;
case IS_FALSE:
diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c
index 4e9f9bde3c..bf33287fd0 100644
--- a/ext/spl/spl_array.c
+++ b/ext/spl/spl_array.c
@@ -348,7 +348,7 @@ fetch_dim_string:
}
return retval;
case IS_RESOURCE:
- zend_error(E_NOTICE, "Resource ID#%d used as offset, casting to integer (%d)", Z_RES_P(offset)->handle, Z_RES_P(offset)->handle);
+ zend_error(E_WARNING, "Resource ID#%d used as offset, casting to integer (%d)", Z_RES_P(offset)->handle, Z_RES_P(offset)->handle);
index = Z_RES_P(offset)->handle;
goto num_index;
case IS_DOUBLE:
diff --git a/ext/spl/tests/bug62978.phpt b/ext/spl/tests/bug62978.phpt
index ec6275346e..7e61d27b89 100644
--- a/ext/spl/tests/bug62978.phpt
+++ b/ext/spl/tests/bug62978.phpt
@@ -46,7 +46,7 @@ Notice: Undefined index: epic_magic in %sbug62978.php on line %d
NULL
bool(false)
-Notice: Resource ID#%d used as offset, casting to integer (%d) in %sbug62978.php on line %d
+Warning: Resource ID#%d used as offset, casting to integer (%d) in %sbug62978.php on line %d
Notice: Undefined offset: %d in %sbug62978.php on line %d
NULL
diff --git a/ext/standard/array.c b/ext/standard/array.c
index ffa695f26d..b8e727d103 100644
--- a/ext/standard/array.c
+++ b/ext/standard/array.c
@@ -40,6 +40,7 @@
#include "php_math.h"
#include "zend_smart_str.h"
#include "zend_bitset.h"
+#include "zend_exceptions.h"
#include "ext/spl/spl_array.h"
/* {{{ defines */
@@ -765,6 +766,7 @@ PHP_FUNCTION(count)
switch (Z_TYPE_P(array)) {
case IS_NULL:
+ /* Intentionally not converted to an exception */
php_error_docref(NULL, E_WARNING, "Parameter must be an array or an object that implements Countable");
RETURN_LONG(0);
break;
@@ -799,11 +801,13 @@ PHP_FUNCTION(count)
}
/* If There's no handler and it doesn't implement Countable then add a warning */
+ /* Intentionally not converted to an exception */
php_error_docref(NULL, E_WARNING, "Parameter must be an array or an object that implements Countable");
RETURN_LONG(1);
break;
}
default:
+ /* Intentionally not converted to an exception */
php_error_docref(NULL, E_WARNING, "Parameter must be an array or an object that implements Countable");
RETURN_LONG(1);
break;
@@ -5212,7 +5216,7 @@ static void php_array_diff(INTERNAL_FUNCTION_PARAMETERS, int behavior, int data_
param_spec = "+f";
diff_data_compare_func = php_array_user_compare;
} else {
- php_error_docref(NULL, E_WARNING, "data_compare_type is %d. This should never happen. Please report as a bug", data_compare_type);
+ ZEND_ASSERT(0 && "Invalid data_compare_type");
return;
}
@@ -6349,9 +6353,22 @@ PHP_FUNCTION(array_key_exists)
case IS_NULL:
RETVAL_BOOL(zend_hash_exists_ind(ht, ZSTR_EMPTY_ALLOC()));
break;
+ case IS_DOUBLE:
+ RETVAL_BOOL(zend_hash_index_exists(ht, zend_dval_to_lval(Z_DVAL_P(key))));
+ break;
+ case IS_FALSE:
+ RETVAL_BOOL(zend_hash_index_exists(ht, 0));
+ break;
+ case IS_TRUE:
+ RETVAL_BOOL(zend_hash_index_exists(ht, 1));
+ break;
+ case IS_RESOURCE:
+ zend_error(E_WARNING, "Resource ID#%d used as offset, casting to integer (%d)", Z_RES_HANDLE_P(key), Z_RES_HANDLE_P(key));
+ RETVAL_BOOL(zend_hash_index_exists(ht, Z_RES_HANDLE_P(key)));
+ break;
default:
- php_error_docref(NULL, E_WARNING, "The first argument should be either a string or an integer");
- RETVAL_FALSE;
+ zend_type_error("Illegal offset type");
+ break;
}
}
/* }}} */
diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php
index de4d22bc3c..c596d216e8 100755
--- a/ext/standard/basic_functions.stub.php
+++ b/ext/standard/basic_functions.stub.php
@@ -63,7 +63,7 @@ function krsort(array &$arg, int $sort_flags = SORT_REGULAR): bool {}
function ksort(array &$arg, int $sort_flags = SORT_REGULAR): bool {}
-/** @param array|Countable $array */
+/** @param array|Countable $var */
function count($var, int $mode = COUNT_NORAML): int {}
function natsort(array &$arg): bool {}
@@ -258,11 +258,8 @@ function array_filter(array $arg, callable $callback = UNKNOWN, int $use_keys =
function array_map(?callable $callback, array $arr1, array ...$arrays): array {}
-/**
- * @param int|string $key
- * @param array|object $search
- */
-function array_key_exists($key, $search): bool {}
+/** @param mixed $key */
+function array_key_exists($key, array $search): bool {}
function array_chunk(array $arg, int $size, bool $preserve_keys = false): array {}
diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h
index 103b44f152..200891a563 100755
--- a/ext/standard/basic_functions_arginfo.h
+++ b/ext/standard/basic_functions_arginfo.h
@@ -341,7 +341,7 @@ ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_key_exists, 0, 2, _IS_BOOL, 0)
ZEND_ARG_INFO(0, key)
- ZEND_ARG_INFO(0, search)
+ ZEND_ARG_TYPE_INFO(0, search, IS_ARRAY, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_chunk, 0, 2, IS_ARRAY, 0)
diff --git a/ext/standard/tests/array/array_key_exists.phpt b/ext/standard/tests/array/array_key_exists.phpt
index 551ef85a67..a436e7363e 100644
--- a/ext/standard/tests/array/array_key_exists.phpt
+++ b/ext/standard/tests/array/array_key_exists.phpt
@@ -70,9 +70,11 @@ foreach ($search_arrays_v as $search_array) {
echo "\n*** Testing error conditions ***\n";
// first args as array
-var_dump( array_key_exists(array(), array()) );
-// first argument as floating point value
-var_dump( array_key_exists(17.5, array(1,23) ) ) ;
+try {
+ array_key_exists(array(), array());
+} catch (TypeError $exception) {
+ echo $exception->getMessage() . "\n";
+}
echo "\n*** Testing operation on objects ***\n";
class key_check
@@ -219,12 +221,7 @@ bool(false)
bool(true)
*** Testing error conditions ***
-
-Warning: array_key_exists(): The first argument should be either a string or an integer in %s on line %d
-bool(false)
-
-Warning: array_key_exists(): The first argument should be either a string or an integer in %s on line %d
-bool(false)
+Illegal offset type
*** Testing operation on objects ***
array_key_exists() expects parameter 2 to be array, object given
diff --git a/ext/standard/tests/array/array_key_exists_variation1.phpt b/ext/standard/tests/array/array_key_exists_variation1.phpt
index c6e8ba7806..2f25dbadee 100644
--- a/ext/standard/tests/array/array_key_exists_variation1.phpt
+++ b/ext/standard/tests/array/array_key_exists_variation1.phpt
@@ -15,7 +15,7 @@ Test array_key_exists() function : usage variations - Pass different data types
echo "*** Testing array_key_exists() : usage variations ***\n";
// Initialise function arguments not being substituted
-$search = array ('zero', 'key' => 'val', 'two');
+$search = array ('zero', 'key' => 'val', 'two', 10 => 'value');
//get an unset variable
$unset_var = 10;
@@ -90,7 +90,11 @@ $inputs = array(
$iterator = 1;
foreach($inputs as $input) {
echo "\n-- Iteration $iterator --\n";
- var_dump( array_key_exists($input, $search) );
+ try {
+ var_dump( array_key_exists($input, $search) );
+ } catch (TypeError $exception) {
+ echo $exception->getMessage() . "\n";
+ }
$iterator++;
};
@@ -114,29 +118,19 @@ bool(false)
bool(false)
-- Iteration 5 --
-
-Warning: array_key_exists(): The first argument should be either a string or an integer in %s on line %d
-bool(false)
+bool(true)
-- Iteration 6 --
-
-Warning: array_key_exists(): The first argument should be either a string or an integer in %s on line %d
bool(false)
-- Iteration 7 --
-
-Warning: array_key_exists(): The first argument should be either a string or an integer in %s on line %d
bool(false)
-- Iteration 8 --
-
-Warning: array_key_exists(): The first argument should be either a string or an integer in %s on line %d
-bool(false)
+bool(true)
-- Iteration 9 --
-
-Warning: array_key_exists(): The first argument should be either a string or an integer in %s on line %d
-bool(false)
+bool(true)
-- Iteration 10 --
bool(false)
@@ -145,24 +139,16 @@ bool(false)
bool(false)
-- Iteration 12 --
-
-Warning: array_key_exists(): The first argument should be either a string or an integer in %s on line %d
-bool(false)
+bool(true)
-- Iteration 13 --
-
-Warning: array_key_exists(): The first argument should be either a string or an integer in %s on line %d
-bool(false)
+bool(true)
-- Iteration 14 --
-
-Warning: array_key_exists(): The first argument should be either a string or an integer in %s on line %d
-bool(false)
+bool(true)
-- Iteration 15 --
-
-Warning: array_key_exists(): The first argument should be either a string or an integer in %s on line %d
-bool(false)
+bool(true)
-- Iteration 16 --
bool(false)
@@ -171,9 +157,7 @@ bool(false)
bool(false)
-- Iteration 18 --
-
-Warning: array_key_exists(): The first argument should be either a string or an integer in %s on line %d
-bool(false)
+Illegal offset type
-- Iteration 19 --
bool(true)
@@ -185,9 +169,7 @@ bool(true)
bool(true)
-- Iteration 22 --
-
-Warning: array_key_exists(): The first argument should be either a string or an integer in %s on line %d
-bool(false)
+Illegal offset type
-- Iteration 23 --
bool(false)
@@ -197,6 +179,6 @@ bool(false)
-- Iteration 25 --
-Warning: array_key_exists(): The first argument should be either a string or an integer in %s on line %d
+Warning: Resource ID#%d used as offset, casting to integer (%d) in %s on line %d
bool(false)
Done
diff --git a/ext/standard/tests/array/array_key_exists_variation3.phpt b/ext/standard/tests/array/array_key_exists_variation3.phpt
index 867b4d9848..11f0125be2 100644
--- a/ext/standard/tests/array/array_key_exists_variation3.phpt
+++ b/ext/standard/tests/array/array_key_exists_variation3.phpt
@@ -23,7 +23,11 @@ $iterator = 1;
foreach($keys as $key) {
echo "\n-- Iteration $iterator --\n";
echo "Pass float as \$key:\n";
- var_dump(array_key_exists($key, $search));
+ try {
+ var_dump(array_key_exists($key, $search));
+ } catch (TypeError $exception) {
+ echo $exception->getMessage() . "\n";
+ }
echo "Cast float to int:\n";
var_dump(array_key_exists((int)$key, $search));
}
@@ -35,25 +39,19 @@ echo "Done";
-- Iteration 1 --
Pass float as $key:
-
-Warning: array_key_exists(): The first argument should be either a string or an integer in %s on line %d
-bool(false)
+bool(true)
Cast float to int:
bool(true)
-- Iteration 1 --
Pass float as $key:
-
-Warning: array_key_exists(): The first argument should be either a string or an integer in %s on line %d
-bool(false)
+bool(true)
Cast float to int:
bool(true)
-- Iteration 1 --
Pass float as $key:
-
-Warning: array_key_exists(): The first argument should be either a string or an integer in %s on line %d
-bool(false)
+bool(true)
Cast float to int:
bool(true)
Done