summaryrefslogtreecommitdiff
path: root/Zend
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2020-11-30 16:45:48 +0100
committerNikita Popov <nikita.ppv@gmail.com>2021-02-11 21:46:13 +0100
commitb10416a652d26577a22fe0b183b2258b20c8bb86 (patch)
tree3b79102286b2307575f487bf97d572ffc292631d /Zend
parentf06895488a5fabd27ac4c2e66a9d311f14d8594e (diff)
downloadphp-git-b10416a652d26577a22fe0b183b2258b20c8bb86.tar.gz
Deprecate passing null to non-nullable arg of internal function
This deprecates passing null to non-nullable scale arguments of internal functions, with the eventual goal of making the behavior consistent with userland functions, where null is never accepted for non-nullable arguments. This change is expected to cause quite a lot of fallout. In most cases, calling code should be adjusted to avoid passing null. In some cases, PHP should be adjusted to make some function arguments nullable. I have already fixed a number of functions before landing this, but feel free to file a bug if you encounter a function that doesn't accept null, but probably should. (The rule of thumb for this to be applicable is that the function must have special behavior for 0 or "", which is distinct from the natural behavior of the parameter.) RFC: https://wiki.php.net/rfc/deprecate_null_to_scalar_internal_arg Closes GH-6475.
Diffstat (limited to 'Zend')
-rw-r--r--Zend/tests/bug43201.phpt12
-rw-r--r--Zend/tests/bug64677.phpt2
-rw-r--r--Zend/tests/class_exists_002.phpt2
-rw-r--r--Zend/tests/exception_001.phpt2
-rw-r--r--Zend/tests/interface_exists_001.phpt2
-rw-r--r--Zend/tests/null_to_non_nullable_special_func.phpt12
-rw-r--r--Zend/tests/nullsafe_operator/013.phpt9
-rw-r--r--Zend/tests/str_or_obj_of_class_zpp.phpt4
-rw-r--r--Zend/tests/str_or_obj_zpp.phpt4
-rw-r--r--Zend/tests/trait_exists_001.phpt2
-rw-r--r--Zend/zend_API.c96
-rw-r--r--Zend/zend_API.h102
-rw-r--r--Zend/zend_execute.c14
-rw-r--r--Zend/zend_vm_def.h12
-rw-r--r--Zend/zend_vm_execute.h36
15 files changed, 213 insertions, 98 deletions
diff --git a/Zend/tests/bug43201.phpt b/Zend/tests/bug43201.phpt
index 49816ea1c1..c93b118e16 100644
--- a/Zend/tests/bug43201.phpt
+++ b/Zend/tests/bug43201.phpt
@@ -30,25 +30,37 @@ Warning: Undefined variable $ref in %s on line %d
Warning: Undefined variable $undef in %s on line %d
+Deprecated: chop(): Passing null to parameter #1 ($string) of type string is deprecated in %s on line %d
+
Notice: Indirect modification of overloaded property Foo::$arr has no effect in %sbug43201.php on line 17
Warning: Undefined variable $undef in %s on line %d
+Deprecated: chop(): Passing null to parameter #1 ($string) of type string is deprecated in %s on line %d
+
Notice: Indirect modification of overloaded property Foo::$arr has no effect in %sbug43201.php on line 17
Warning: Undefined variable $undef in %s on line %d
+Deprecated: chop(): Passing null to parameter #1 ($string) of type string is deprecated in %s on line %d
+
Notice: Indirect modification of overloaded property Foo::$arr has no effect in %sbug43201.php on line 17
Warning: Undefined variable $undef in %s on line %d
+Deprecated: chop(): Passing null to parameter #1 ($string) of type string is deprecated in %s on line %d
+
Notice: Indirect modification of overloaded property Foo::$arr has no effect in %sbug43201.php on line 17
Warning: Undefined variable $undef in %s on line %d
+Deprecated: chop(): Passing null to parameter #1 ($string) of type string is deprecated in %s on line %d
+
Notice: Indirect modification of overloaded property Foo::$arr has no effect in %sbug43201.php on line 17
Warning: Undefined variable $undef in %s on line %d
+Deprecated: chop(): Passing null to parameter #1 ($string) of type string is deprecated in %s on line %d
+
Notice: Indirect modification of overloaded property Foo::$arr has no effect in %sbug43201.php on line 17
ok
diff --git a/Zend/tests/bug64677.phpt b/Zend/tests/bug64677.phpt
index 2dcd00ce0a..c3b168bd83 100644
--- a/Zend/tests/bug64677.phpt
+++ b/Zend/tests/bug64677.phpt
@@ -7,7 +7,7 @@ class cat {
}
}
$cat = new cat();
-$cat->show_output('Files: ', trim(`cd .`)); // this gives invalid args to shell_exec
+$cat->show_output('Files: ', trim((string) `cd .`)); // this gives invalid args to shell_exec
$cat->show_output('Files: ', `cd .`); // this causes a segmentation fault
$cat->show_output(`cd .`); // this causes a segmentation fault
diff --git a/Zend/tests/class_exists_002.phpt b/Zend/tests/class_exists_002.phpt
index 5e5df1d371..e020c1d623 100644
--- a/Zend/tests/class_exists_002.phpt
+++ b/Zend/tests/class_exists_002.phpt
@@ -8,7 +8,6 @@ class foo {
}
var_dump(class_exists(''));
-var_dump(class_exists(NULL));
var_dump(class_exists('FOO'));
var_dump(class_exists('bar'));
var_dump(class_exists(1));
@@ -16,7 +15,6 @@ var_dump(class_exists(1));
?>
--EXPECT--
bool(false)
-bool(false)
bool(true)
bool(false)
bool(false)
diff --git a/Zend/tests/exception_001.phpt b/Zend/tests/exception_001.phpt
index 232ef012ed..aba29d4aa3 100644
--- a/Zend/tests/exception_001.phpt
+++ b/Zend/tests/exception_001.phpt
@@ -7,7 +7,7 @@ try {
try {
try {
try {
- throw new Exception(NULL);
+ throw new Exception();
} catch (Exception $e) {
var_dump($e->getMessage());
throw $e;
diff --git a/Zend/tests/interface_exists_001.phpt b/Zend/tests/interface_exists_001.phpt
index 84e9c6df1e..4bc01221a8 100644
--- a/Zend/tests/interface_exists_001.phpt
+++ b/Zend/tests/interface_exists_001.phpt
@@ -8,10 +8,8 @@ interface foo {
var_dump(interface_exists('foo'));
var_dump(interface_exists(1));
-var_dump(interface_exists(NULL));
?>
--EXPECT--
bool(true)
bool(false)
-bool(false)
diff --git a/Zend/tests/null_to_non_nullable_special_func.phpt b/Zend/tests/null_to_non_nullable_special_func.phpt
new file mode 100644
index 0000000000..9dc1c96f72
--- /dev/null
+++ b/Zend/tests/null_to_non_nullable_special_func.phpt
@@ -0,0 +1,12 @@
+--TEST--
+Test null arg behavior for special functions
+--FILE--
+<?php
+
+$null = null;
+var_dump(strlen($null));
+
+?>
+--EXPECTF--
+Deprecated: strlen(): Passing null to parameter #1 ($string) of type string is deprecated in %s on line %d
+int(0)
diff --git a/Zend/tests/nullsafe_operator/013.phpt b/Zend/tests/nullsafe_operator/013.phpt
index fd1fbc9006..595f292f6f 100644
--- a/Zend/tests/nullsafe_operator/013.phpt
+++ b/Zend/tests/nullsafe_operator/013.phpt
@@ -38,14 +38,21 @@ dump_error(fn() => array_key_exists('foo', $foo?->foo()));
?>
--EXPECTF--
+Deprecated: strlen(): Passing null to parameter #1 ($string) of type string is deprecated in %s on line %d
int(0)
bool(true)
bool(false)
bool(false)
bool(false)
bool(false)
+
+Deprecated: defined(): Passing null to parameter #1 ($constant_name) of type string is deprecated in %s on line %d
bool(false)
+
+Deprecated: chr(): Passing null to parameter #1 ($codepoint) of type int is deprecated in %s on line %d
string(1) "%s"
+
+Deprecated: ord(): Passing null to parameter #1 ($character) of type string is deprecated in %s on line %d
int(0)
string(98) "call_user_func_array(): Argument #1 ($function) must be a valid callback, no array or string given"
string(77) "call_user_func_array(): Argument #2 ($args) must be of type array, null given"
@@ -55,6 +62,8 @@ string(4) "NULL"
string(52) "func_num_args() expects exactly 0 arguments, 1 given"
string(52) "func_get_args() expects exactly 0 arguments, 1 given"
string(69) "array_slice(): Argument #1 ($array) must be of type array, null given"
+
+Deprecated: array_slice(): Passing null to parameter #2 ($offset) of type int is deprecated in %s on line %d
array(1) {
[0]=>
string(3) "foo"
diff --git a/Zend/tests/str_or_obj_of_class_zpp.phpt b/Zend/tests/str_or_obj_of_class_zpp.phpt
index 6f6a155895..04a321a692 100644
--- a/Zend/tests/str_or_obj_of_class_zpp.phpt
+++ b/Zend/tests/str_or_obj_of_class_zpp.phpt
@@ -51,9 +51,11 @@ try {
}
?>
---EXPECT--
+--EXPECTF--
string(6) "string"
string(1) "1"
+
+Deprecated: zend_string_or_stdclass(): Passing null to parameter #1 ($param) of type string is deprecated in %s on line %d
string(0) ""
object(stdClass)#1 (0) {
}
diff --git a/Zend/tests/str_or_obj_zpp.phpt b/Zend/tests/str_or_obj_zpp.phpt
index 6328c61b2d..00eec7a688 100644
--- a/Zend/tests/str_or_obj_zpp.phpt
+++ b/Zend/tests/str_or_obj_zpp.phpt
@@ -34,9 +34,11 @@ try {
}
?>
---EXPECT--
+--EXPECTF--
string(6) "string"
string(1) "1"
+
+Deprecated: zend_string_or_object(): Passing null to parameter #1 ($param) of type object|string is deprecated in %s on line %d
string(0) ""
object(stdClass)#1 (0) {
}
diff --git a/Zend/tests/trait_exists_001.phpt b/Zend/tests/trait_exists_001.phpt
index 8a7c55d586..8699b07cef 100644
--- a/Zend/tests/trait_exists_001.phpt
+++ b/Zend/tests/trait_exists_001.phpt
@@ -8,10 +8,8 @@ trait foo {
var_dump(trait_exists('foo'));
var_dump(trait_exists(1));
-var_dump(trait_exists(NULL));
?>
--EXPECT--
bool(true)
bool(false)
-bool(false)
diff --git a/Zend/zend_API.c b/Zend/zend_API.c
index abfbb411a5..6aa9a043ff 100644
--- a/Zend/zend_API.c
+++ b/Zend/zend_API.c
@@ -426,9 +426,41 @@ ZEND_API bool ZEND_FASTCALL zend_parse_arg_class(zval *arg, zend_class_entry **p
}
/* }}} */
-ZEND_API bool ZEND_FASTCALL zend_parse_arg_bool_weak(zval *arg, bool *dest) /* {{{ */
+static ZEND_COLD bool zend_null_arg_deprecated(const char *fallback_type, uint32_t arg_num) {
+ zend_function *func = EG(current_execute_data)->func;
+ ZEND_ASSERT(arg_num > 0);
+ uint32_t arg_offset = arg_num - 1;
+ if (arg_offset >= func->common.num_args) {
+ ZEND_ASSERT(func->common.fn_flags & ZEND_ACC_VARIADIC);
+ arg_offset = func->common.num_args;
+ }
+
+ zend_arg_info *arg_info = &func->common.arg_info[arg_offset];
+ zend_string *func_name = get_active_function_or_method_name();
+ const char *arg_name = get_active_function_arg_name(arg_num);
+
+ /* If no type is specified in arginfo, use the specified fallback_type determined through
+ * zend_parse_parameters instead. */
+ zend_string *type_str = zend_type_to_string(arg_info->type);
+ const char *type = type_str ? ZSTR_VAL(type_str) : fallback_type;
+ zend_error(E_DEPRECATED,
+ "%s(): Passing null to parameter #%" PRIu32 "%s%s%s of type %s is deprecated",
+ ZSTR_VAL(func_name), arg_num,
+ arg_name ? " ($" : "", arg_name ? arg_name : "", arg_name ? ")" : "",
+ type);
+ zend_string_release(func_name);
+ if (type_str) {
+ zend_string_release(type_str);
+ }
+ return !EG(exception);
+}
+
+ZEND_API bool ZEND_FASTCALL zend_parse_arg_bool_weak(zval *arg, bool *dest, uint32_t arg_num) /* {{{ */
{
if (EXPECTED(Z_TYPE_P(arg) <= IS_STRING)) {
+ if (UNEXPECTED(Z_TYPE_P(arg) == IS_NULL) && !zend_null_arg_deprecated("bool", arg_num)) {
+ return 0;
+ }
*dest = zend_is_true(arg);
} else {
return 0;
@@ -437,16 +469,16 @@ ZEND_API bool ZEND_FASTCALL zend_parse_arg_bool_weak(zval *arg, bool *dest) /* {
}
/* }}} */
-ZEND_API bool ZEND_FASTCALL zend_parse_arg_bool_slow(zval *arg, bool *dest) /* {{{ */
+ZEND_API bool ZEND_FASTCALL zend_parse_arg_bool_slow(zval *arg, bool *dest, uint32_t arg_num) /* {{{ */
{
if (UNEXPECTED(ZEND_ARG_USES_STRICT_TYPES())) {
return 0;
}
- return zend_parse_arg_bool_weak(arg, dest);
+ return zend_parse_arg_bool_weak(arg, dest, arg_num);
}
/* }}} */
-ZEND_API bool ZEND_FASTCALL zend_parse_arg_long_weak(zval *arg, zend_long *dest) /* {{{ */
+ZEND_API bool ZEND_FASTCALL zend_parse_arg_long_weak(zval *arg, zend_long *dest, uint32_t arg_num) /* {{{ */
{
if (EXPECTED(Z_TYPE_P(arg) == IS_DOUBLE)) {
if (UNEXPECTED(zend_isnan(Z_DVAL_P(arg)))) {
@@ -479,6 +511,9 @@ ZEND_API bool ZEND_FASTCALL zend_parse_arg_long_weak(zval *arg, zend_long *dest)
return 0;
}
} else if (EXPECTED(Z_TYPE_P(arg) < IS_TRUE)) {
+ if (UNEXPECTED(Z_TYPE_P(arg) == IS_NULL) && !zend_null_arg_deprecated("int", arg_num)) {
+ return 0;
+ }
*dest = 0;
} else if (EXPECTED(Z_TYPE_P(arg) == IS_TRUE)) {
*dest = 1;
@@ -489,16 +524,16 @@ ZEND_API bool ZEND_FASTCALL zend_parse_arg_long_weak(zval *arg, zend_long *dest)
}
/* }}} */
-ZEND_API bool ZEND_FASTCALL zend_parse_arg_long_slow(zval *arg, zend_long *dest) /* {{{ */
+ZEND_API bool ZEND_FASTCALL zend_parse_arg_long_slow(zval *arg, zend_long *dest, uint32_t arg_num) /* {{{ */
{
if (UNEXPECTED(ZEND_ARG_USES_STRICT_TYPES())) {
return 0;
}
- return zend_parse_arg_long_weak(arg, dest);
+ return zend_parse_arg_long_weak(arg, dest, arg_num);
}
/* }}} */
-ZEND_API bool ZEND_FASTCALL zend_parse_arg_double_weak(zval *arg, double *dest) /* {{{ */
+ZEND_API bool ZEND_FASTCALL zend_parse_arg_double_weak(zval *arg, double *dest, uint32_t arg_num) /* {{{ */
{
if (EXPECTED(Z_TYPE_P(arg) == IS_LONG)) {
*dest = (double)Z_LVAL_P(arg);
@@ -517,6 +552,9 @@ ZEND_API bool ZEND_FASTCALL zend_parse_arg_double_weak(zval *arg, double *dest)
return 0;
}
} else if (EXPECTED(Z_TYPE_P(arg) < IS_TRUE)) {
+ if (UNEXPECTED(Z_TYPE_P(arg) == IS_NULL) && !zend_null_arg_deprecated("float", arg_num)) {
+ return 0;
+ }
*dest = 0.0;
} else if (EXPECTED(Z_TYPE_P(arg) == IS_TRUE)) {
*dest = 1.0;
@@ -527,7 +565,7 @@ ZEND_API bool ZEND_FASTCALL zend_parse_arg_double_weak(zval *arg, double *dest)
}
/* }}} */
-ZEND_API bool ZEND_FASTCALL zend_parse_arg_double_slow(zval *arg, double *dest) /* {{{ */
+ZEND_API bool ZEND_FASTCALL zend_parse_arg_double_slow(zval *arg, double *dest, uint32_t arg_num) /* {{{ */
{
if (EXPECTED(Z_TYPE_P(arg) == IS_LONG)) {
/* SSTH Exception: IS_LONG may be accepted instead as IS_DOUBLE */
@@ -535,11 +573,11 @@ ZEND_API bool ZEND_FASTCALL zend_parse_arg_double_slow(zval *arg, double *dest)
} else if (UNEXPECTED(ZEND_ARG_USES_STRICT_TYPES())) {
return 0;
}
- return zend_parse_arg_double_weak(arg, dest);
+ return zend_parse_arg_double_weak(arg, dest, arg_num);
}
/* }}} */
-ZEND_API bool ZEND_FASTCALL zend_parse_arg_number_slow(zval *arg, zval **dest) /* {{{ */
+ZEND_API bool ZEND_FASTCALL zend_parse_arg_number_slow(zval *arg, zval **dest, uint32_t arg_num) /* {{{ */
{
if (UNEXPECTED(ZEND_ARG_USES_STRICT_TYPES())) {
return 0;
@@ -558,6 +596,9 @@ ZEND_API bool ZEND_FASTCALL zend_parse_arg_number_slow(zval *arg, zval **dest) /
}
zend_string_release(str);
} else if (Z_TYPE_P(arg) < IS_TRUE) {
+ if (UNEXPECTED(Z_TYPE_P(arg) == IS_NULL) && !zend_null_arg_deprecated("int|float", arg_num)) {
+ return 0;
+ }
ZVAL_LONG(arg, 0);
} else if (Z_TYPE_P(arg) == IS_TRUE) {
ZVAL_LONG(arg, 1);
@@ -569,9 +610,12 @@ ZEND_API bool ZEND_FASTCALL zend_parse_arg_number_slow(zval *arg, zval **dest) /
}
/* }}} */
-ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_weak(zval *arg, zend_string **dest) /* {{{ */
+ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_weak(zval *arg, zend_string **dest, uint32_t arg_num) /* {{{ */
{
if (EXPECTED(Z_TYPE_P(arg) < IS_STRING)) {
+ if (UNEXPECTED(Z_TYPE_P(arg) == IS_NULL) && !zend_null_arg_deprecated("string", arg_num)) {
+ return 0;
+ }
convert_to_string(arg);
*dest = Z_STR_P(arg);
} else if (UNEXPECTED(Z_TYPE_P(arg) == IS_OBJECT)) {
@@ -591,24 +635,24 @@ ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_weak(zval *arg, zend_string **des
}
/* }}} */
-ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_slow(zval *arg, zend_string **dest) /* {{{ */
+ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_slow(zval *arg, zend_string **dest, uint32_t arg_num) /* {{{ */
{
if (UNEXPECTED(ZEND_ARG_USES_STRICT_TYPES())) {
return 0;
}
- return zend_parse_arg_str_weak(arg, dest);
+ return zend_parse_arg_str_weak(arg, dest, arg_num);
}
/* }}} */
-ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_or_long_slow(zval *arg, zend_string **dest_str, zend_long *dest_long) /* {{{ */
+ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_or_long_slow(zval *arg, zend_string **dest_str, zend_long *dest_long, uint32_t arg_num) /* {{{ */
{
if (UNEXPECTED(ZEND_ARG_USES_STRICT_TYPES())) {
return 0;
}
- if (zend_parse_arg_long_weak(arg, dest_long)) {
+ if (zend_parse_arg_long_weak(arg, dest_long, arg_num)) {
*dest_str = NULL;
return 1;
- } else if (zend_parse_arg_str_weak(arg, dest_str)) {
+ } else if (zend_parse_arg_str_weak(arg, dest_str, arg_num)) {
*dest_long = 0;
return 1;
} else {
@@ -617,7 +661,7 @@ ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_or_long_slow(zval *arg, zend_stri
}
/* }}} */
-static const char *zend_parse_arg_impl(zval *arg, va_list *va, const char **spec, char **error) /* {{{ */
+static const char *zend_parse_arg_impl(zval *arg, va_list *va, const char **spec, char **error, uint32_t arg_num) /* {{{ */
{
const char *spec_walk = *spec;
char c = *spec_walk++;
@@ -650,7 +694,7 @@ static const char *zend_parse_arg_impl(zval *arg, va_list *va, const char **spec
is_null = va_arg(*va, bool *);
}
- if (!zend_parse_arg_long(arg, p, is_null, check_null)) {
+ if (!zend_parse_arg_long(arg, p, is_null, check_null, arg_num)) {
return check_null ? "?int" : "int";
}
}
@@ -665,7 +709,7 @@ static const char *zend_parse_arg_impl(zval *arg, va_list *va, const char **spec
is_null = va_arg(*va, bool *);
}
- if (!zend_parse_arg_double(arg, p, is_null, check_null)) {
+ if (!zend_parse_arg_double(arg, p, is_null, check_null, arg_num)) {
return check_null ? "?float" : "float";
}
}
@@ -675,7 +719,7 @@ static const char *zend_parse_arg_impl(zval *arg, va_list *va, const char **spec
{
zval **p = va_arg(*va, zval **);
- if (!zend_parse_arg_number(arg, p, check_null)) {
+ if (!zend_parse_arg_number(arg, p, check_null, arg_num)) {
return check_null ? "int|float|null" : "int|float";
}
}
@@ -685,7 +729,7 @@ static const char *zend_parse_arg_impl(zval *arg, va_list *va, const char **spec
{
char **p = va_arg(*va, char **);
size_t *pl = va_arg(*va, size_t *);
- if (!zend_parse_arg_string(arg, p, pl, check_null)) {
+ if (!zend_parse_arg_string(arg, p, pl, check_null, arg_num)) {
return check_null ? "?string" : "string";
}
}
@@ -695,7 +739,7 @@ static const char *zend_parse_arg_impl(zval *arg, va_list *va, const char **spec
{
char **p = va_arg(*va, char **);
size_t *pl = va_arg(*va, size_t *);
- if (!zend_parse_arg_path(arg, p, pl, check_null)) {
+ if (!zend_parse_arg_path(arg, p, pl, check_null, arg_num)) {
if (Z_TYPE_P(arg) == IS_STRING) {
zend_spprintf(error, 0, "must not contain any null bytes");
return "";
@@ -709,7 +753,7 @@ static const char *zend_parse_arg_impl(zval *arg, va_list *va, const char **spec
case 'P':
{
zend_string **str = va_arg(*va, zend_string **);
- if (!zend_parse_arg_path_str(arg, str, check_null)) {
+ if (!zend_parse_arg_path_str(arg, str, check_null, arg_num)) {
if (Z_TYPE_P(arg) == IS_STRING) {
zend_spprintf(error, 0, "must not contain any null bytes");
return "";
@@ -723,7 +767,7 @@ static const char *zend_parse_arg_impl(zval *arg, va_list *va, const char **spec
case 'S':
{
zend_string **str = va_arg(*va, zend_string **);
- if (!zend_parse_arg_str(arg, str, check_null)) {
+ if (!zend_parse_arg_str(arg, str, check_null, arg_num)) {
return check_null ? "?string" : "string";
}
}
@@ -738,7 +782,7 @@ static const char *zend_parse_arg_impl(zval *arg, va_list *va, const char **spec
is_null = va_arg(*va, bool *);
}
- if (!zend_parse_arg_bool(arg, p, is_null, check_null)) {
+ if (!zend_parse_arg_bool(arg, p, is_null, check_null, arg_num)) {
return check_null ? "?bool" : "bool";
}
}
@@ -899,7 +943,7 @@ static zend_result zend_parse_arg(uint32_t arg_num, zval *arg, va_list *va, cons
const char *expected_type = NULL;
char *error = NULL;
- expected_type = zend_parse_arg_impl(arg, va, spec, &error);
+ expected_type = zend_parse_arg_impl(arg, va, spec, &error, arg_num);
if (expected_type) {
if (EG(exception)) {
return FAILURE;
diff --git a/Zend/zend_API.h b/Zend/zend_API.h
index 6c867b2869..a811d9c533 100644
--- a/Zend/zend_API.h
+++ b/Zend/zend_API.h
@@ -1450,7 +1450,7 @@ ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *
/* old "b" */
#define Z_PARAM_BOOL_EX(dest, is_null, check_null, deref) \
Z_PARAM_PROLOGUE(deref, 0); \
- if (UNEXPECTED(!zend_parse_arg_bool(_arg, &dest, &is_null, check_null))) { \
+ if (UNEXPECTED(!zend_parse_arg_bool(_arg, &dest, &is_null, check_null, _i))) { \
_expected_type = check_null ? Z_EXPECTED_BOOL_OR_NULL : Z_EXPECTED_BOOL; \
_error_code = ZPP_ERROR_WRONG_ARG; \
break; \
@@ -1492,7 +1492,7 @@ ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *
#define Z_PARAM_OBJ_OR_STR_EX(destination_object, destination_string, allow_null) \
Z_PARAM_PROLOGUE(0, 0); \
- if (UNEXPECTED(!zend_parse_arg_obj_or_str(_arg, &destination_object, NULL, &destination_string, allow_null))) { \
+ if (UNEXPECTED(!zend_parse_arg_obj_or_str(_arg, &destination_object, NULL, &destination_string, allow_null, _i))) { \
_expected_type = allow_null ? Z_EXPECTED_OBJECT_OR_STRING_OR_NULL : Z_EXPECTED_OBJECT_OR_STRING; \
_error_code = ZPP_ERROR_WRONG_ARG; \
break; \
@@ -1506,7 +1506,7 @@ ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *
#define Z_PARAM_OBJ_OF_CLASS_OR_STR_EX(destination_object, base_ce, destination_string, allow_null) \
Z_PARAM_PROLOGUE(0, 0); \
- if (UNEXPECTED(!zend_parse_arg_obj_or_str(_arg, &destination_object, base_ce, &destination_string, allow_null))) { \
+ if (UNEXPECTED(!zend_parse_arg_obj_or_str(_arg, &destination_object, base_ce, &destination_string, allow_null, _i))) { \
if (base_ce) { \
_error = ZSTR_VAL((base_ce)->name); \
_error_code = allow_null ? ZPP_ERROR_WRONG_CLASS_OR_STRING_OR_NULL : ZPP_ERROR_WRONG_CLASS_OR_STRING; \
@@ -1527,7 +1527,7 @@ ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *
/* old "d" */
#define Z_PARAM_DOUBLE_EX(dest, is_null, check_null, deref) \
Z_PARAM_PROLOGUE(deref, 0); \
- if (UNEXPECTED(!zend_parse_arg_double(_arg, &dest, &is_null, check_null))) { \
+ if (UNEXPECTED(!zend_parse_arg_double(_arg, &dest, &is_null, check_null, _i))) { \
_expected_type = check_null ? Z_EXPECTED_DOUBLE_OR_NULL : Z_EXPECTED_DOUBLE; \
_error_code = ZPP_ERROR_WRONG_ARG; \
break; \
@@ -1578,7 +1578,7 @@ ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *
#define Z_PARAM_ARRAY_HT_OR_LONG_EX(dest_ht, dest_long, is_null, allow_null) \
Z_PARAM_PROLOGUE(0, 0); \
- if (UNEXPECTED(!zend_parse_arg_array_ht_or_long(_arg, &dest_ht, &dest_long, &is_null, allow_null))) { \
+ if (UNEXPECTED(!zend_parse_arg_array_ht_or_long(_arg, &dest_ht, &dest_long, &is_null, allow_null, _i))) { \
_expected_type = allow_null ? Z_EXPECTED_ARRAY_OR_LONG_OR_NULL : Z_EXPECTED_ARRAY_OR_LONG; \
_error_code = ZPP_ERROR_WRONG_ARG; \
break; \
@@ -1608,7 +1608,7 @@ ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *
/* old "l" */
#define Z_PARAM_LONG_EX(dest, is_null, check_null, deref) \
Z_PARAM_PROLOGUE(deref, 0); \
- if (UNEXPECTED(!zend_parse_arg_long(_arg, &dest, &is_null, check_null))) { \
+ if (UNEXPECTED(!zend_parse_arg_long(_arg, &dest, &is_null, check_null, _i))) { \
_expected_type = check_null ? Z_EXPECTED_LONG_OR_NULL : Z_EXPECTED_LONG; \
_error_code = ZPP_ERROR_WRONG_ARG; \
break; \
@@ -1623,7 +1623,7 @@ ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *
/* old "n" */
#define Z_PARAM_NUMBER_EX(dest, check_null) \
Z_PARAM_PROLOGUE(0, 0); \
- if (UNEXPECTED(!zend_parse_arg_number(_arg, &dest, check_null))) { \
+ if (UNEXPECTED(!zend_parse_arg_number(_arg, &dest, check_null, _i))) { \
_expected_type = check_null ? Z_EXPECTED_NUMBER_OR_NULL : Z_EXPECTED_NUMBER; \
_error_code = ZPP_ERROR_WRONG_ARG; \
break; \
@@ -1709,7 +1709,7 @@ ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *
#define Z_PARAM_OBJ_OF_CLASS_OR_LONG_EX(dest_obj, _ce, dest_long, is_null, allow_null) \
Z_PARAM_PROLOGUE(0, 0); \
- if (UNEXPECTED(!zend_parse_arg_obj_or_long(_arg, &dest_obj, _ce, &dest_long, &is_null, allow_null))) { \
+ if (UNEXPECTED(!zend_parse_arg_obj_or_long(_arg, &dest_obj, _ce, &dest_long, &is_null, allow_null, _i))) { \
_error = ZSTR_VAL((_ce)->name); \
_error_code = allow_null ? ZPP_ERROR_WRONG_CLASS_OR_LONG_OR_NULL : ZPP_ERROR_WRONG_CLASS_OR_LONG; \
break; \
@@ -1724,7 +1724,7 @@ ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *
/* old "p" */
#define Z_PARAM_PATH_EX(dest, dest_len, check_null, deref) \
Z_PARAM_PROLOGUE(deref, 0); \
- if (UNEXPECTED(!zend_parse_arg_path(_arg, &dest, &dest_len, check_null))) { \
+ if (UNEXPECTED(!zend_parse_arg_path(_arg, &dest, &dest_len, check_null, _i))) { \
_expected_type = check_null ? Z_EXPECTED_PATH_OR_NULL : Z_EXPECTED_PATH; \
_error_code = ZPP_ERROR_WRONG_ARG; \
break; \
@@ -1739,7 +1739,7 @@ ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *
/* old "P" */
#define Z_PARAM_PATH_STR_EX(dest, check_null, deref) \
Z_PARAM_PROLOGUE(deref, 0); \
- if (UNEXPECTED(!zend_parse_arg_path_str(_arg, &dest, check_null))) { \
+ if (UNEXPECTED(!zend_parse_arg_path_str(_arg, &dest, check_null, _i))) { \
_expected_type = check_null ? Z_EXPECTED_PATH_OR_NULL : Z_EXPECTED_PATH; \
_error_code = ZPP_ERROR_WRONG_ARG; \
break; \
@@ -1769,7 +1769,7 @@ ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *
/* old "s" */
#define Z_PARAM_STRING_EX(dest, dest_len, check_null, deref) \
Z_PARAM_PROLOGUE(deref, 0); \
- if (UNEXPECTED(!zend_parse_arg_string(_arg, &dest, &dest_len, check_null))) { \
+ if (UNEXPECTED(!zend_parse_arg_string(_arg, &dest, &dest_len, check_null, _i))) { \
_expected_type = check_null ? Z_EXPECTED_STRING_OR_NULL : Z_EXPECTED_STRING; \
_error_code = ZPP_ERROR_WRONG_ARG; \
break; \
@@ -1784,7 +1784,7 @@ ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *
/* old "S" */
#define Z_PARAM_STR_EX(dest, check_null, deref) \
Z_PARAM_PROLOGUE(deref, 0); \
- if (UNEXPECTED(!zend_parse_arg_str(_arg, &dest, check_null))) { \
+ if (UNEXPECTED(!zend_parse_arg_str(_arg, &dest, check_null, _i))) { \
_expected_type = check_null ? Z_EXPECTED_STRING_OR_NULL : Z_EXPECTED_STRING; \
_error_code = ZPP_ERROR_WRONG_ARG; \
break; \
@@ -1849,7 +1849,7 @@ ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *
#define Z_PARAM_ARRAY_HT_OR_STR_EX(dest_ht, dest_str, allow_null) \
Z_PARAM_PROLOGUE(0, 0); \
- if (UNEXPECTED(!zend_parse_arg_array_ht_or_str(_arg, &dest_ht, &dest_str, allow_null))) { \
+ if (UNEXPECTED(!zend_parse_arg_array_ht_or_str(_arg, &dest_ht, &dest_str, allow_null, _i))) { \
_expected_type = allow_null ? Z_EXPECTED_ARRAY_OR_STRING_OR_NULL : Z_EXPECTED_ARRAY_OR_STRING; \
_error_code = ZPP_ERROR_WRONG_ARG; \
break; \
@@ -1863,7 +1863,7 @@ ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *
#define Z_PARAM_STR_OR_LONG_EX(dest_str, dest_long, is_null, allow_null) \
Z_PARAM_PROLOGUE(0, 0); \
- if (UNEXPECTED(!zend_parse_arg_str_or_long(_arg, &dest_str, &dest_long, &is_null, allow_null))) { \
+ if (UNEXPECTED(!zend_parse_arg_str_or_long(_arg, &dest_str, &dest_long, &is_null, allow_null, _i))) { \
_expected_type = allow_null ? Z_EXPECTED_STRING_OR_LONG_OR_NULL : Z_EXPECTED_STRING_OR_LONG; \
_error_code = ZPP_ERROR_WRONG_ARG; \
break; \
@@ -1880,18 +1880,18 @@ ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *
/* Inlined implementations shared by new and old parameter parsing APIs */
ZEND_API bool ZEND_FASTCALL zend_parse_arg_class(zval *arg, zend_class_entry **pce, uint32_t num, bool check_null);
-ZEND_API bool ZEND_FASTCALL zend_parse_arg_bool_slow(zval *arg, bool *dest);
-ZEND_API bool ZEND_FASTCALL zend_parse_arg_bool_weak(zval *arg, bool *dest);
-ZEND_API bool ZEND_FASTCALL zend_parse_arg_long_slow(zval *arg, zend_long *dest);
-ZEND_API bool ZEND_FASTCALL zend_parse_arg_long_weak(zval *arg, zend_long *dest);
-ZEND_API bool ZEND_FASTCALL zend_parse_arg_double_slow(zval *arg, double *dest);
-ZEND_API bool ZEND_FASTCALL zend_parse_arg_double_weak(zval *arg, double *dest);
-ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_slow(zval *arg, zend_string **dest);
-ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_weak(zval *arg, zend_string **dest);
-ZEND_API bool ZEND_FASTCALL zend_parse_arg_number_slow(zval *arg, zval **dest);
-ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_or_long_slow(zval *arg, zend_string **dest_str, zend_long *dest_long);
-
-static zend_always_inline bool zend_parse_arg_bool(zval *arg, bool *dest, bool *is_null, bool check_null)
+ZEND_API bool ZEND_FASTCALL zend_parse_arg_bool_slow(zval *arg, bool *dest, uint32_t arg_num);
+ZEND_API bool ZEND_FASTCALL zend_parse_arg_bool_weak(zval *arg, bool *dest, uint32_t arg_num);
+ZEND_API bool ZEND_FASTCALL zend_parse_arg_long_slow(zval *arg, zend_long *dest, uint32_t arg_num);
+ZEND_API bool ZEND_FASTCALL zend_parse_arg_long_weak(zval *arg, zend_long *dest, uint32_t arg_num);
+ZEND_API bool ZEND_FASTCALL zend_parse_arg_double_slow(zval *arg, double *dest, uint32_t arg_num);
+ZEND_API bool ZEND_FASTCALL zend_parse_arg_double_weak(zval *arg, double *dest, uint32_t arg_num);
+ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_slow(zval *arg, zend_string **dest, uint32_t arg_num);
+ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_weak(zval *arg, zend_string **dest, uint32_t arg_num);
+ZEND_API bool ZEND_FASTCALL zend_parse_arg_number_slow(zval *arg, zval **dest, uint32_t arg_num);
+ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_or_long_slow(zval *arg, zend_string **dest_str, zend_long *dest_long, uint32_t arg_num);
+
+static zend_always_inline bool zend_parse_arg_bool(zval *arg, bool *dest, bool *is_null, bool check_null, uint32_t arg_num)
{
if (check_null) {
*is_null = 0;
@@ -1904,12 +1904,12 @@ static zend_always_inline bool zend_parse_arg_bool(zval *arg, bool *dest, bool *
*is_null = 1;
*dest = 0;
} else {
- return zend_parse_arg_bool_slow(arg, dest);
+ return zend_parse_arg_bool_slow(arg, dest, arg_num);
}
return 1;
}
-static zend_always_inline bool zend_parse_arg_long(zval *arg, zend_long *dest, bool *is_null, bool check_null)
+static zend_always_inline bool zend_parse_arg_long(zval *arg, zend_long *dest, bool *is_null, bool check_null, uint32_t arg_num)
{
if (check_null) {
*is_null = 0;
@@ -1920,12 +1920,12 @@ static zend_always_inline bool zend_parse_arg_long(zval *arg, zend_long *dest, b
*is_null = 1;
*dest = 0;
} else {
- return zend_parse_arg_long_slow(arg, dest);
+ return zend_parse_arg_long_slow(arg, dest, arg_num);
}
return 1;
}
-static zend_always_inline bool zend_parse_arg_double(zval *arg, double *dest, bool *is_null, bool check_null)
+static zend_always_inline bool zend_parse_arg_double(zval *arg, double *dest, bool *is_null, bool check_null, uint32_t arg_num)
{
if (check_null) {
*is_null = 0;
@@ -1936,40 +1936,40 @@ static zend_always_inline bool zend_parse_arg_double(zval *arg, double *dest, bo
*is_null = 1;
*dest = 0.0;
} else {
- return zend_parse_arg_double_slow(arg, dest);
+ return zend_parse_arg_double_slow(arg, dest, arg_num);
}
return 1;
}
-static zend_always_inline bool zend_parse_arg_number(zval *arg, zval **dest, bool check_null)
+static zend_always_inline bool zend_parse_arg_number(zval *arg, zval **dest, bool check_null, uint32_t arg_num)
{
if (EXPECTED(Z_TYPE_P(arg) == IS_LONG || Z_TYPE_P(arg) == IS_DOUBLE)) {
*dest = arg;
} else if (check_null && EXPECTED(Z_TYPE_P(arg) == IS_NULL)) {
*dest = NULL;
} else {
- return zend_parse_arg_number_slow(arg, dest);
+ return zend_parse_arg_number_slow(arg, dest, arg_num);
}
return 1;
}
-static zend_always_inline bool zend_parse_arg_str(zval *arg, zend_string **dest, bool check_null)
+static zend_always_inline bool zend_parse_arg_str(zval *arg, zend_string **dest, bool check_null, uint32_t arg_num)
{
if (EXPECTED(Z_TYPE_P(arg) == IS_STRING)) {
*dest = Z_STR_P(arg);
} else if (check_null && Z_TYPE_P(arg) == IS_NULL) {
*dest = NULL;
} else {
- return zend_parse_arg_str_slow(arg, dest);
+ return zend_parse_arg_str_slow(arg, dest, arg_num);
}
return 1;
}
-static zend_always_inline bool zend_parse_arg_string(zval *arg, char **dest, size_t *dest_len, bool check_null)
+static zend_always_inline bool zend_parse_arg_string(zval *arg, char **dest, size_t *dest_len, bool check_null, uint32_t arg_num)
{
zend_string *str;
- if (!zend_parse_arg_str(arg, &str, check_null)) {
+ if (!zend_parse_arg_str(arg, &str, check_null, arg_num)) {
return 0;
}
if (check_null && UNEXPECTED(!str)) {
@@ -1982,20 +1982,20 @@ static zend_always_inline bool zend_parse_arg_string(zval *arg, char **dest, siz
return 1;
}
-static zend_always_inline bool zend_parse_arg_path_str(zval *arg, zend_string **dest, bool check_null)
+static zend_always_inline bool zend_parse_arg_path_str(zval *arg, zend_string **dest, bool check_null, uint32_t arg_num)
{
- if (!zend_parse_arg_str(arg, dest, check_null) ||
+ if (!zend_parse_arg_str(arg, dest, check_null, arg_num) ||
(*dest && UNEXPECTED(CHECK_NULL_PATH(ZSTR_VAL(*dest), ZSTR_LEN(*dest))))) {
return 0;
}
return 1;
}
-static zend_always_inline bool zend_parse_arg_path(zval *arg, char **dest, size_t *dest_len, bool check_null)
+static zend_always_inline bool zend_parse_arg_path(zval *arg, char **dest, size_t *dest_len, bool check_null, uint32_t arg_num)
{
zend_string *str;
- if (!zend_parse_arg_path_str(arg, &str, check_null)) {
+ if (!zend_parse_arg_path_str(arg, &str, check_null, arg_num)) {
return 0;
}
if (check_null && UNEXPECTED(!str)) {
@@ -2060,7 +2060,7 @@ static zend_always_inline bool zend_parse_arg_array_ht(zval *arg, HashTable **de
}
static zend_always_inline bool zend_parse_arg_array_ht_or_long(
- zval *arg, HashTable **dest_ht, zend_long *dest_long, bool *is_null, bool allow_null
+ zval *arg, HashTable **dest_ht, zend_long *dest_long, bool *is_null, bool allow_null, uint32_t arg_num
) {
if (allow_null) {
*is_null = 0;
@@ -2076,7 +2076,7 @@ static zend_always_inline bool zend_parse_arg_array_ht_or_long(
*is_null = 1;
} else {
*dest_ht = NULL;
- return zend_parse_arg_long_slow(arg, dest_long);
+ return zend_parse_arg_long_slow(arg, dest_long, arg_num);
}
return 1;
@@ -2109,7 +2109,7 @@ static zend_always_inline bool zend_parse_arg_obj(zval *arg, zend_object **dest,
}
static zend_always_inline bool zend_parse_arg_obj_or_long(
- zval *arg, zend_object **dest_obj, zend_class_entry *ce, zend_long *dest_long, bool *is_null, bool allow_null
+ zval *arg, zend_object **dest_obj, zend_class_entry *ce, zend_long *dest_long, bool *is_null, bool allow_null, uint32_t arg_num
) {
if (allow_null) {
*is_null = 0;
@@ -2125,7 +2125,7 @@ static zend_always_inline bool zend_parse_arg_obj_or_long(
*is_null = 1;
} else {
*dest_obj = NULL;
- return zend_parse_arg_long_slow(arg, dest_long);
+ return zend_parse_arg_long_slow(arg, dest_long, arg_num);
}
return 1;
@@ -2173,7 +2173,7 @@ static zend_always_inline void zend_parse_arg_zval_deref(zval *arg, zval **dest,
}
static zend_always_inline bool zend_parse_arg_array_ht_or_str(
- zval *arg, HashTable **dest_ht, zend_string **dest_str, bool allow_null)
+ zval *arg, HashTable **dest_ht, zend_string **dest_str, bool allow_null, uint32_t arg_num)
{
if (EXPECTED(Z_TYPE_P(arg) == IS_STRING)) {
*dest_ht = NULL;
@@ -2186,13 +2186,13 @@ static zend_always_inline bool zend_parse_arg_array_ht_or_str(
*dest_str = NULL;
} else {
*dest_ht = NULL;
- return zend_parse_arg_str_slow(arg, dest_str);
+ return zend_parse_arg_str_slow(arg, dest_str, arg_num);
}
return 1;
}
static zend_always_inline bool zend_parse_arg_str_or_long(zval *arg, zend_string **dest_str, zend_long *dest_long,
- bool *is_null, bool allow_null)
+ bool *is_null, bool allow_null, uint32_t arg_num)
{
if (allow_null) {
*is_null = 0;
@@ -2206,7 +2206,7 @@ static zend_always_inline bool zend_parse_arg_str_or_long(zval *arg, zend_string
*dest_str = NULL;
*is_null = 1;
} else {
- return zend_parse_arg_str_or_long_slow(arg, dest_str, dest_long);
+ return zend_parse_arg_str_or_long_slow(arg, dest_str, dest_long, arg_num);
}
return 1;
}
@@ -2230,7 +2230,7 @@ static zend_always_inline bool zend_parse_arg_obj_or_class_name(
}
static zend_always_inline bool zend_parse_arg_obj_or_str(
- zval *arg, zend_object **destination_object, zend_class_entry *base_ce, zend_string **destination_string, bool allow_null
+ zval *arg, zend_object **destination_object, zend_class_entry *base_ce, zend_string **destination_string, bool allow_null, uint32_t arg_num
) {
if (EXPECTED(Z_TYPE_P(arg) == IS_OBJECT)) {
if (!base_ce || EXPECTED(instanceof_function(Z_OBJCE_P(arg), base_ce))) {
@@ -2241,7 +2241,7 @@ static zend_always_inline bool zend_parse_arg_obj_or_str(
}
*destination_object = NULL;
- return zend_parse_arg_str(arg, destination_string, allow_null);
+ return zend_parse_arg_str(arg, destination_string, allow_null, arg_num);
}
END_EXTERN_C()
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index 753eef4267..2a93cece8a 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -739,22 +739,22 @@ static bool zend_verify_weak_scalar_type_hint(uint32_t type_mask, zval *arg)
ZVAL_DOUBLE(arg, dval);
return 1;
}
- } else if (zend_parse_arg_long_weak(arg, &lval)) {
+ } else if (zend_parse_arg_long_weak(arg, &lval, 0)) {
zval_ptr_dtor(arg);
ZVAL_LONG(arg, lval);
return 1;
}
}
- if ((type_mask & MAY_BE_DOUBLE) && zend_parse_arg_double_weak(arg, &dval)) {
+ if ((type_mask & MAY_BE_DOUBLE) && zend_parse_arg_double_weak(arg, &dval, 0)) {
zval_ptr_dtor(arg);
ZVAL_DOUBLE(arg, dval);
return 1;
}
- if ((type_mask & MAY_BE_STRING) && zend_parse_arg_str_weak(arg, &str)) {
+ if ((type_mask & MAY_BE_STRING) && zend_parse_arg_str_weak(arg, &str, 0)) {
/* on success "arg" is converted to IS_STRING */
return 1;
}
- if ((type_mask & MAY_BE_BOOL) == MAY_BE_BOOL && zend_parse_arg_bool_weak(arg, &bval)) {
+ if ((type_mask & MAY_BE_BOOL) == MAY_BE_BOOL && zend_parse_arg_bool_weak(arg, &bval, 0)) {
zval_ptr_dtor(arg);
ZVAL_BOOL(arg, bval);
return 1;
@@ -781,16 +781,16 @@ static bool zend_verify_weak_scalar_type_hint_no_sideeffect(uint32_t type_mask,
double dval;
bool bval;
- if ((type_mask & MAY_BE_LONG) && zend_parse_arg_long_weak(arg, &lval)) {
+ if ((type_mask & MAY_BE_LONG) && zend_parse_arg_long_weak(arg, &lval, 0)) {
return 1;
}
- if ((type_mask & MAY_BE_DOUBLE) && zend_parse_arg_double_weak(arg, &dval)) {
+ if ((type_mask & MAY_BE_DOUBLE) && zend_parse_arg_double_weak(arg, &dval, 0)) {
return 1;
}
if ((type_mask & MAY_BE_STRING) && can_convert_to_string(arg)) {
return 1;
}
- if ((type_mask & MAY_BE_BOOL) == MAY_BE_BOOL && zend_parse_arg_bool_weak(arg, &bval)) {
+ if ((type_mask & MAY_BE_BOOL) == MAY_BE_BOOL && zend_parse_arg_bool_weak(arg, &bval, 0)) {
return 1;
}
return 0;
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 98b8b51d7f..7d0b30ff2b 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -8310,8 +8310,18 @@ ZEND_VM_COLD_CONST_HANDLER(121, ZEND_STRLEN, CONST|TMPVAR|CV, ANY)
zend_string *str;
zval tmp;
+ if (UNEXPECTED(Z_TYPE_P(value) == IS_NULL)) {
+ zend_error(E_DEPRECATED,
+ "strlen(): Passing null to parameter #1 ($string) of type string is deprecated");
+ if (UNEXPECTED(EG(exception))) {
+ HANDLE_EXCEPTION();
+ }
+ ZVAL_LONG(EX_VAR(opline->result.var), 0);
+ break;
+ }
+
ZVAL_COPY(&tmp, value);
- if (zend_parse_arg_str_weak(&tmp, &str)) {
+ if (zend_parse_arg_str_weak(&tmp, &str, 1)) {
ZVAL_LONG(EX_VAR(opline->result.var), ZSTR_LEN(str));
zval_ptr_dtor(&tmp);
break;
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index d680541f03..0fe4fb5bb5 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -5286,8 +5286,18 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_STRLEN_SPEC_CONST
zend_string *str;
zval tmp;
+ if (UNEXPECTED(Z_TYPE_P(value) == IS_NULL)) {
+ zend_error(E_DEPRECATED,
+ "strlen(): Passing null to parameter #1 ($string) of type string is deprecated");
+ if (UNEXPECTED(EG(exception))) {
+ HANDLE_EXCEPTION();
+ }
+ ZVAL_LONG(EX_VAR(opline->result.var), 0);
+ break;
+ }
+
ZVAL_COPY(&tmp, value);
- if (zend_parse_arg_str_weak(&tmp, &str)) {
+ if (zend_parse_arg_str_weak(&tmp, &str, 1)) {
ZVAL_LONG(EX_VAR(opline->result.var), ZSTR_LEN(str));
zval_ptr_dtor(&tmp);
break;
@@ -14459,8 +14469,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_STRLEN_SPEC_TMPVAR_HANDLER(ZEN
zend_string *str;
zval tmp;
+ if (UNEXPECTED(Z_TYPE_P(value) == IS_NULL)) {
+ zend_error(E_DEPRECATED,
+ "strlen(): Passing null to parameter #1 ($string) of type string is deprecated");
+ if (UNEXPECTED(EG(exception))) {
+ HANDLE_EXCEPTION();
+ }
+ ZVAL_LONG(EX_VAR(opline->result.var), 0);
+ break;
+ }
+
ZVAL_COPY(&tmp, value);
- if (zend_parse_arg_str_weak(&tmp, &str)) {
+ if (zend_parse_arg_str_weak(&tmp, &str, 1)) {
ZVAL_LONG(EX_VAR(opline->result.var), ZSTR_LEN(str));
zval_ptr_dtor(&tmp);
break;
@@ -38546,8 +38566,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_STRLEN_SPEC_CV_HANDLER(ZEND_OP
zend_string *str;
zval tmp;
+ if (UNEXPECTED(Z_TYPE_P(value) == IS_NULL)) {
+ zend_error(E_DEPRECATED,
+ "strlen(): Passing null to parameter #1 ($string) of type string is deprecated");
+ if (UNEXPECTED(EG(exception))) {
+ HANDLE_EXCEPTION();
+ }
+ ZVAL_LONG(EX_VAR(opline->result.var), 0);
+ break;
+ }
+
ZVAL_COPY(&tmp, value);
- if (zend_parse_arg_str_weak(&tmp, &str)) {
+ if (zend_parse_arg_str_weak(&tmp, &str, 1)) {
ZVAL_LONG(EX_VAR(opline->result.var), ZSTR_LEN(str));
zval_ptr_dtor(&tmp);
break;