diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2020-11-30 16:45:48 +0100 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2021-02-11 21:46:13 +0100 |
commit | b10416a652d26577a22fe0b183b2258b20c8bb86 (patch) | |
tree | 3b79102286b2307575f487bf97d572ffc292631d /Zend | |
parent | f06895488a5fabd27ac4c2e66a9d311f14d8594e (diff) | |
download | php-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.phpt | 12 | ||||
-rw-r--r-- | Zend/tests/bug64677.phpt | 2 | ||||
-rw-r--r-- | Zend/tests/class_exists_002.phpt | 2 | ||||
-rw-r--r-- | Zend/tests/exception_001.phpt | 2 | ||||
-rw-r--r-- | Zend/tests/interface_exists_001.phpt | 2 | ||||
-rw-r--r-- | Zend/tests/null_to_non_nullable_special_func.phpt | 12 | ||||
-rw-r--r-- | Zend/tests/nullsafe_operator/013.phpt | 9 | ||||
-rw-r--r-- | Zend/tests/str_or_obj_of_class_zpp.phpt | 4 | ||||
-rw-r--r-- | Zend/tests/str_or_obj_zpp.phpt | 4 | ||||
-rw-r--r-- | Zend/tests/trait_exists_001.phpt | 2 | ||||
-rw-r--r-- | Zend/zend_API.c | 96 | ||||
-rw-r--r-- | Zend/zend_API.h | 102 | ||||
-rw-r--r-- | Zend/zend_execute.c | 14 | ||||
-rw-r--r-- | Zend/zend_vm_def.h | 12 | ||||
-rw-r--r-- | Zend/zend_vm_execute.h | 36 |
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; |