summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMáté Kocsis <kocsismate@woohoolabs.com>2020-09-14 11:59:32 +0200
committerMáté Kocsis <kocsismate@woohoolabs.com>2020-09-14 11:59:32 +0200
commit46c0c82a0fdb877fc222a13bd92422e543b160c6 (patch)
treeb21003ade62d5f2b5d47edae7f145ce51f5e7294
parent1c81a3456372693dc4036fd7a3deb143cbb3aeef (diff)
downloadphp-git-46c0c82a0fdb877fc222a13bd92422e543b160c6.tar.gz
Declare array|int and object-of-class|int types in stubs
Closes GH-6081 Co-Authored-By: Nikita Popov <nikic@php.net>
-rw-r--r--Zend/zend_API.c32
-rw-r--r--Zend/zend_API.h77
-rw-r--r--ext/filter/filter.c149
-rw-r--r--ext/filter/filter.stub.php12
-rw-r--r--ext/filter/filter_arginfo.h10
-rw-r--r--ext/filter/tests/010.phpt6
-rw-r--r--ext/filter/tests/011.phpt12
-rw-r--r--ext/filter/tests/039.phpt63
-rw-r--r--ext/filter/tests/057.phpt38
-rw-r--r--ext/intl/calendar/calendar_class.cpp4
-rw-r--r--ext/intl/calendar/calendar_class.h5
-rw-r--r--ext/intl/dateformat/dateformat.stub.php6
-rw-r--r--ext/intl/dateformat/dateformat_arginfo.h13
-rw-r--r--ext/intl/dateformat/dateformat_attrcpp.cpp24
-rw-r--r--ext/intl/dateformat/dateformat_create.cpp52
-rw-r--r--ext/intl/dateformat/dateformat_format_object.cpp2
-rw-r--r--ext/intl/dateformat/dateformat_helpers.cpp28
-rw-r--r--ext/intl/dateformat/dateformat_helpers.h11
-rw-r--r--ext/intl/php_intl.stub.php10
-rw-r--r--ext/intl/php_intl_arginfo.h6
-rw-r--r--ext/intl/tests/dateformat___construct_bad_tz_cal.phpt4
-rw-r--r--ext/session/session.c42
-rw-r--r--ext/session/session.stub.php3
-rw-r--r--ext/session/session_arginfo.h8
-rw-r--r--ext/session/tests/session_set_cookie_params_variation7.phpt12
-rwxr-xr-xext/standard/basic_functions.stub.php12
-rwxr-xr-xext/standard/basic_functions_arginfo.h10
-rw-r--r--ext/standard/head.c37
-rw-r--r--ext/standard/string.c62
29 files changed, 467 insertions, 283 deletions
diff --git a/Zend/zend_API.c b/Zend/zend_API.c
index 14abdd1a38..ee0e361ed9 100644
--- a/Zend/zend_API.c
+++ b/Zend/zend_API.c
@@ -221,15 +221,21 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_error(int error_code,
case ZPP_ERROR_WRONG_CLASS_OR_NULL:
zend_wrong_parameter_class_or_null_error(num, name, arg);
break;
- case ZPP_ERROR_WRONG_ARG:
- zend_wrong_parameter_type_error(num, expected_type, arg);
- break;
case ZPP_ERROR_WRONG_CLASS_OR_STRING:
zend_wrong_parameter_class_or_string_error(num, name, arg);
break;
case ZPP_ERROR_WRONG_CLASS_OR_STRING_OR_NULL:
zend_wrong_parameter_class_or_string_or_null_error(num, name, arg);
break;
+ case ZPP_ERROR_WRONG_CLASS_OR_LONG:
+ zend_wrong_parameter_class_or_long_error(num, name, arg);
+ break;
+ case ZPP_ERROR_WRONG_CLASS_OR_LONG_OR_NULL:
+ zend_wrong_parameter_class_or_long_or_null_error(num, name, arg);
+ break;
+ case ZPP_ERROR_WRONG_ARG:
+ zend_wrong_parameter_type_error(num, expected_type, arg);
+ break;
case ZPP_ERROR_UNEXPECTED_EXTRA_NAMED:
zend_unexpected_extra_named_error();
break;
@@ -280,6 +286,26 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_null_error(u
}
/* }}} */
+ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_long_error(uint32_t num, const char *name, zval *arg) /* {{{ */
+{
+ if (EG(exception)) {
+ return;
+ }
+
+ zend_argument_type_error(num, "must be of type %s|int, %s given", name, zend_zval_type_name(arg));
+}
+/* }}} */
+
+ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_long_or_null_error(uint32_t num, const char *name, zval *arg) /* {{{ */
+{
+ if (EG(exception)) {
+ return;
+ }
+
+ zend_argument_type_error(num, "must be of type %s|int|null, %s given", name, zend_zval_type_name(arg));
+}
+/* }}} */
+
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_string_error(uint32_t num, const char *name, zval *arg) /* {{{ */
{
if (EG(exception)) {
diff --git a/Zend/zend_API.h b/Zend/zend_API.h
index 226ca60d1b..da9a57d5c6 100644
--- a/Zend/zend_API.h
+++ b/Zend/zend_API.h
@@ -1209,6 +1209,8 @@ static zend_always_inline zval *zend_try_array_init(zval *zv)
_(Z_EXPECTED_STRING_OR_NULL, "of type ?string") \
_(Z_EXPECTED_ARRAY, "of type array") \
_(Z_EXPECTED_ARRAY_OR_NULL, "of type ?array") \
+ _(Z_EXPECTED_ARRAY_OR_LONG, "of type array|int") \
+ _(Z_EXPECTED_ARRAY_OR_LONG_OR_NULL, "of type array|int|null") \
_(Z_EXPECTED_ITERABLE, "of type iterable") \
_(Z_EXPECTED_ITERABLE_OR_NULL, "of type ?iterable") \
_(Z_EXPECTED_FUNC, "a valid callback") \
@@ -1248,6 +1250,8 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_error(int error_code,
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_type_error(uint32_t num, zend_expected_type expected_type, zval *arg);
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_error(uint32_t num, const char *name, zval *arg);
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_null_error(uint32_t num, const char *name, zval *arg);
+ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_long_error(uint32_t num, const char *name, zval *arg);
+ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_long_or_null_error(uint32_t num, const char *name, zval *arg);
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_string_error(uint32_t num, const char *name, zval *arg);
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_string_or_null_error(uint32_t num, const char *name, zval *arg);
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_callback_error(uint32_t num, char *error);
@@ -1261,11 +1265,13 @@ ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *
#define ZPP_ERROR_WRONG_CALLBACK 2
#define ZPP_ERROR_WRONG_CLASS 3
#define ZPP_ERROR_WRONG_CLASS_OR_NULL 4
-#define ZPP_ERROR_WRONG_ARG 5
-#define ZPP_ERROR_WRONG_COUNT 6
-#define ZPP_ERROR_WRONG_CLASS_OR_STRING 7
-#define ZPP_ERROR_WRONG_CLASS_OR_STRING_OR_NULL 8
-#define ZPP_ERROR_UNEXPECTED_EXTRA_NAMED 9
+#define ZPP_ERROR_WRONG_CLASS_OR_STRING 5
+#define ZPP_ERROR_WRONG_CLASS_OR_STRING_OR_NULL 6
+#define ZPP_ERROR_WRONG_CLASS_OR_LONG 7
+#define ZPP_ERROR_WRONG_CLASS_OR_LONG_OR_NULL 8
+#define ZPP_ERROR_WRONG_ARG 9
+#define ZPP_ERROR_WRONG_COUNT 10
+#define ZPP_ERROR_UNEXPECTED_EXTRA_NAMED 11
#define ZEND_PARSE_PARAMETERS_START_EX(flags, min_num_args, max_num_args) do { \
const int _flags = (flags); \
@@ -1675,6 +1681,21 @@ ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *
#define Z_PARAM_OBJ_OF_CLASS_OR_NULL(dest, _ce) \
Z_PARAM_OBJ_OF_CLASS_EX(dest, _ce, 1, 0)
+
+#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))) { \
+ _error = ZSTR_VAL((_ce)->name); \
+ _error_code = allow_null ? ZPP_ERROR_WRONG_CLASS_OR_LONG_OR_NULL : ZPP_ERROR_WRONG_CLASS_OR_LONG; \
+ break; \
+ }
+
+#define Z_PARAM_OBJ_OF_CLASS_OR_LONG(dest_obj, _ce, dest_long) \
+ Z_PARAM_OBJ_OF_CLASS_OR_LONG_EX(dest_obj, _ce, dest_long, _dummy, 0)
+
+#define Z_PARAM_OBJ_OF_CLASS_OR_LONG_OR_NULL(dest_obj, _ce, dest_long, is_null) \
+ Z_PARAM_OBJ_OF_CLASS_OR_LONG_EX(dest_obj, _ce, dest_long, is_null, 1)
+
/* old "p" */
#define Z_PARAM_PATH_EX2(dest, dest_len, check_null, deref, separate) \
Z_PARAM_PROLOGUE(deref, separate); \
@@ -2028,6 +2049,29 @@ static zend_always_inline bool zend_parse_arg_array_ht(zval *arg, HashTable **de
return 1;
}
+static zend_always_inline bool zend_parse_arg_array_ht_or_long(
+ zval *arg, HashTable **dest_ht, zend_long *dest_long, zend_bool *is_null, bool allow_null
+) {
+ if (allow_null) {
+ *is_null = 0;
+ }
+
+ if (EXPECTED(Z_TYPE_P(arg) == IS_ARRAY)) {
+ *dest_ht = Z_ARRVAL_P(arg);
+ } else if (EXPECTED(Z_TYPE_P(arg) == IS_LONG)) {
+ *dest_ht = NULL;
+ *dest_long = Z_LVAL_P(arg);
+ } else if (allow_null && EXPECTED(Z_TYPE_P(arg) == IS_NULL)) {
+ *dest_ht = NULL;
+ *is_null = 1;
+ } else {
+ *dest_ht = NULL;
+ return zend_parse_arg_long_slow(arg, dest_long);
+ }
+
+ return 1;
+}
+
static zend_always_inline bool zend_parse_arg_object(zval *arg, zval **dest, zend_class_entry *ce, bool check_null)
{
if (EXPECTED(Z_TYPE_P(arg) == IS_OBJECT) &&
@@ -2054,6 +2098,29 @@ static zend_always_inline bool zend_parse_arg_obj(zval *arg, zend_object **dest,
return 1;
}
+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, zend_bool *is_null, bool allow_null
+) {
+ if (allow_null) {
+ *is_null = 0;
+ }
+
+ if (EXPECTED(Z_TYPE_P(arg) == IS_OBJECT) && EXPECTED(instanceof_function(Z_OBJCE_P(arg), ce) != 0)) {
+ *dest_obj = Z_OBJ_P(arg);
+ } else if (EXPECTED(Z_TYPE_P(arg) == IS_LONG)) {
+ *dest_obj = NULL;
+ *dest_long = Z_LVAL_P(arg);
+ } else if (allow_null && EXPECTED(Z_TYPE_P(arg) == IS_NULL)) {
+ *dest_obj = NULL;
+ *is_null = 1;
+ } else {
+ *dest_obj = NULL;
+ return zend_parse_arg_long_slow(arg, dest_long);
+ }
+
+ return 1;
+}
+
static zend_always_inline bool zend_parse_arg_resource(zval *arg, zval **dest, bool check_null)
{
if (EXPECTED(Z_TYPE_P(arg) == IS_RESOURCE)) {
diff --git a/ext/filter/filter.c b/ext/filter/filter.c
index 37fac29de9..4aa9368213 100644
--- a/ext/filter/filter.c
+++ b/ext/filter/filter.c
@@ -524,31 +524,31 @@ PHP_FUNCTION(filter_has_var)
}
/* }}} */
-static void php_filter_call(zval *filtered, zend_long filter, zval *filter_args, const int copy, zend_long filter_flags) /* {{{ */
-{
+static void php_filter_call(
+ zval *filtered, zend_long filter, HashTable *filter_args_ht, zend_long filter_args_long,
+ const int copy, zend_long filter_flags
+) /* {{{ */ {
zval *options = NULL;
zval *option;
char *charset = NULL;
- if (filter_args && Z_TYPE_P(filter_args) != IS_ARRAY) {
- zend_long lval = zval_get_long(filter_args);
-
+ if (!filter_args_ht) {
if (filter != -1) { /* handler for array apply */
/* filter_args is the filter_flags */
- filter_flags = lval;
+ filter_flags = filter_args_long;
if (!(filter_flags & FILTER_REQUIRE_ARRAY || filter_flags & FILTER_FORCE_ARRAY)) {
filter_flags |= FILTER_REQUIRE_SCALAR;
}
} else {
- filter = lval;
+ filter = filter_args_long;
}
- } else if (filter_args) {
- if ((option = zend_hash_str_find(Z_ARRVAL_P(filter_args), "filter", sizeof("filter") - 1)) != NULL) {
+ } else {
+ if ((option = zend_hash_str_find(filter_args_ht, "filter", sizeof("filter") - 1)) != NULL) {
filter = zval_get_long(option);
}
- if ((option = zend_hash_str_find(Z_ARRVAL_P(filter_args), "flags", sizeof("flags") - 1)) != NULL) {
+ if ((option = zend_hash_str_find(filter_args_ht, "flags", sizeof("flags") - 1)) != NULL) {
filter_flags = zval_get_long(option);
if (!(filter_flags & FILTER_REQUIRE_ARRAY || filter_flags & FILTER_FORCE_ARRAY)) {
@@ -556,7 +556,7 @@ static void php_filter_call(zval *filtered, zend_long filter, zval *filter_args,
}
}
- if ((option = zend_hash_str_find_deref(Z_ARRVAL_P(filter_args), "options", sizeof("options") - 1)) != NULL) {
+ if ((option = zend_hash_str_find_deref(filter_args_ht, "options", sizeof("options") - 1)) != NULL) {
if (filter != FILTER_CALLBACK) {
if (Z_TYPE_P(option) == IS_ARRAY) {
options = option;
@@ -601,21 +601,19 @@ static void php_filter_call(zval *filtered, zend_long filter, zval *filter_args,
}
/* }}} */
-static void php_filter_array_handler(zval *input, zval *op, zval *return_value, zend_bool add_empty) /* {{{ */
-{
+static void php_filter_array_handler(zval *input, HashTable *op_ht, zend_long op_long,
+ zval *return_value, zend_bool add_empty
+) /* {{{ */ {
zend_string *arg_key;
zval *tmp, *arg_elm;
- if (!op) {
+ if (!op_ht) {
ZVAL_DUP(return_value, input);
- php_filter_call(return_value, FILTER_DEFAULT, NULL, 0, FILTER_REQUIRE_ARRAY);
- } else if (Z_TYPE_P(op) == IS_LONG) {
- ZVAL_DUP(return_value, input);
- php_filter_call(return_value, Z_LVAL_P(op), NULL, 0, FILTER_REQUIRE_ARRAY);
- } else if (Z_TYPE_P(op) == IS_ARRAY) {
+ php_filter_call(return_value, -1, NULL, op_long, 0, FILTER_REQUIRE_ARRAY);
+ } else {
array_init(return_value);
- ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(op), arg_key, arg_elm) {
+ ZEND_HASH_FOREACH_STR_KEY_VAL(op_ht, arg_key, arg_elm) {
if (arg_key == NULL) {
zend_argument_type_error(2, "must contain only string keys");
RETURN_THROWS();
@@ -632,12 +630,14 @@ static void php_filter_array_handler(zval *input, zval *op, zval *return_value,
zval nval;
ZVAL_DEREF(tmp);
ZVAL_DUP(&nval, tmp);
- php_filter_call(&nval, -1, arg_elm, 0, FILTER_REQUIRE_SCALAR);
+ php_filter_call(&nval, -1,
+ Z_TYPE_P(arg_elm) == IS_ARRAY ? Z_ARRVAL_P(arg_elm) : NULL,
+ Z_TYPE_P(arg_elm) == IS_ARRAY ? 0 : zval_get_long(arg_elm),
+ 0, FILTER_REQUIRE_SCALAR
+ );
zend_hash_update(Z_ARRVAL_P(return_value), arg_key, &nval);
}
} ZEND_HASH_FOREACH_END();
- } else {
- RETURN_FALSE;
}
}
/* }}} */
@@ -646,15 +646,21 @@ static void php_filter_array_handler(zval *input, zval *op, zval *return_value,
PHP_FUNCTION(filter_input)
{
zend_long fetch_from, filter = FILTER_DEFAULT;
- zval *filter_args = NULL, *tmp;
- zval *input = NULL;
+ zval *input = NULL, *tmp;
zend_string *var;
+ HashTable *filter_args_ht = NULL;
+ zend_long filter_args_long = 0;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "lS|lz", &fetch_from, &var, &filter, &filter_args) == FAILURE) {
- RETURN_THROWS();
- }
+ ZEND_PARSE_PARAMETERS_START(2, 4)
+ Z_PARAM_LONG(fetch_from)
+ Z_PARAM_STR(var)
+ Z_PARAM_OPTIONAL
+ Z_PARAM_LONG(filter)
+ Z_PARAM_ARRAY_HT_OR_LONG(filter_args_ht, filter_args_long)
+ ZEND_PARSE_PARAMETERS_END();
if (!PHP_FILTER_ID_EXISTS(filter)) {
+ php_error_docref(NULL, E_WARNING, "Unknown filter with ID " ZEND_LONG_FMT, filter);
RETURN_FALSE;
}
@@ -666,16 +672,17 @@ PHP_FUNCTION(filter_input)
if (!input || (tmp = zend_hash_find(Z_ARRVAL_P(input), var)) == NULL) {
zend_long filter_flags = 0;
zval *option, *opt, *def;
- if (filter_args) {
- if (Z_TYPE_P(filter_args) == IS_LONG) {
- filter_flags = Z_LVAL_P(filter_args);
- } else if (Z_TYPE_P(filter_args) == IS_ARRAY && (option = zend_hash_str_find(Z_ARRVAL_P(filter_args), "flags", sizeof("flags") - 1)) != NULL) {
+ if (!filter_args_ht) {
+ filter_flags = filter_args_long;
+ } else {
+ if ((option = zend_hash_str_find(filter_args_ht, "flags", sizeof("flags") - 1)) != NULL) {
filter_flags = zval_get_long(option);
}
- if (Z_TYPE_P(filter_args) == IS_ARRAY &&
- (opt = zend_hash_str_find_deref(Z_ARRVAL_P(filter_args), "options", sizeof("options") - 1)) != NULL &&
+
+ if ((opt = zend_hash_str_find_deref(filter_args_ht, "options", sizeof("options") - 1)) != NULL &&
Z_TYPE_P(opt) == IS_ARRAY &&
- (def = zend_hash_str_find_deref(Z_ARRVAL_P(opt), "default", sizeof("default") - 1)) != NULL) {
+ (def = zend_hash_str_find_deref(Z_ARRVAL_P(opt), "default", sizeof("default") - 1)) != NULL
+ ) {
ZVAL_COPY(return_value, def);
return;
}
@@ -695,7 +702,7 @@ PHP_FUNCTION(filter_input)
ZVAL_DUP(return_value, tmp);
- php_filter_call(return_value, filter, filter_args, 1, FILTER_REQUIRE_SCALAR);
+ php_filter_call(return_value, filter, filter_args_ht, filter_args_long, 1, FILTER_REQUIRE_SCALAR);
}
/* }}} */
@@ -703,19 +710,25 @@ PHP_FUNCTION(filter_input)
PHP_FUNCTION(filter_var)
{
zend_long filter = FILTER_DEFAULT;
- zval *filter_args = NULL, *data;
+ zval *data;
+ HashTable *filter_args_ht = NULL;
+ zend_long filter_args_long = 0;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "z|lz", &data, &filter, &filter_args) == FAILURE) {
- RETURN_THROWS();
- }
+ ZEND_PARSE_PARAMETERS_START(1, 3)
+ Z_PARAM_ZVAL(data)
+ Z_PARAM_OPTIONAL
+ Z_PARAM_LONG(filter)
+ Z_PARAM_ARRAY_HT_OR_LONG(filter_args_ht, filter_args_long)
+ ZEND_PARSE_PARAMETERS_END();
if (!PHP_FILTER_ID_EXISTS(filter)) {
+ php_error_docref(NULL, E_WARNING, "Unknown filter with ID " ZEND_LONG_FMT, filter);
RETURN_FALSE;
}
ZVAL_DUP(return_value, data);
- php_filter_call(return_value, filter, filter_args, 1, FILTER_REQUIRE_SCALAR);
+ php_filter_call(return_value, filter, filter_args_ht, filter_args_long, 1, FILTER_REQUIRE_SCALAR);
}
/* }}} */
@@ -723,14 +736,20 @@ PHP_FUNCTION(filter_var)
PHP_FUNCTION(filter_input_array)
{
zend_long fetch_from;
- zval *array_input = NULL, *op = NULL;
+ zval *array_input = NULL;
zend_bool add_empty = 1;
-
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|zb", &fetch_from, &op, &add_empty) == FAILURE) {
- RETURN_THROWS();
- }
-
- if (op && (Z_TYPE_P(op) != IS_ARRAY) && !(Z_TYPE_P(op) == IS_LONG && PHP_FILTER_ID_EXISTS(Z_LVAL_P(op)))) {
+ HashTable *op_ht = NULL;
+ zend_long op_long = FILTER_DEFAULT;
+
+ ZEND_PARSE_PARAMETERS_START(1, 3)
+ Z_PARAM_LONG(fetch_from)
+ Z_PARAM_OPTIONAL
+ Z_PARAM_ARRAY_HT_OR_LONG(op_ht, op_long)
+ Z_PARAM_BOOL(add_empty)
+ ZEND_PARSE_PARAMETERS_END();
+
+ if (!op_ht && !PHP_FILTER_ID_EXISTS(op_long)) {
+ php_error_docref(NULL, E_WARNING, "Unknown filter with ID " ZEND_LONG_FMT, op_long);
RETURN_FALSE;
}
@@ -742,12 +761,10 @@ PHP_FUNCTION(filter_input_array)
if (!array_input) {
zend_long filter_flags = 0;
zval *option;
- if (op) {
- if (Z_TYPE_P(op) == IS_LONG) {
- filter_flags = Z_LVAL_P(op);
- } else if (Z_TYPE_P(op) == IS_ARRAY && (option = zend_hash_str_find(Z_ARRVAL_P(op), "flags", sizeof("flags") - 1)) != NULL) {
- filter_flags = zval_get_long(option);
- }
+ if (op_long) {
+ filter_flags = op_long;
+ } else if (op_ht && (option = zend_hash_str_find(op_ht, "flags", sizeof("flags") - 1)) != NULL) {
+ filter_flags = zval_get_long(option);
}
/* The FILTER_NULL_ON_FAILURE flag inverts the usual return values of
@@ -762,25 +779,31 @@ PHP_FUNCTION(filter_input_array)
}
}
- php_filter_array_handler(array_input, op, return_value, add_empty);
+ php_filter_array_handler(array_input, op_ht, op_long, return_value, add_empty);
}
/* }}} */
/* {{{ Returns an array with all arguments defined in 'definition'. */
PHP_FUNCTION(filter_var_array)
{
- zval *array_input = NULL, *op = NULL;
+ zval *array_input = NULL;
zend_bool add_empty = 1;
-
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "a|zb", &array_input, &op, &add_empty) == FAILURE) {
- RETURN_THROWS();
- }
-
- if (op && (Z_TYPE_P(op) != IS_ARRAY) && !(Z_TYPE_P(op) == IS_LONG && PHP_FILTER_ID_EXISTS(Z_LVAL_P(op)))) {
+ HashTable *op_ht = NULL;
+ zend_long op_long = FILTER_DEFAULT;
+
+ ZEND_PARSE_PARAMETERS_START(1, 3)
+ Z_PARAM_ARRAY(array_input)
+ Z_PARAM_OPTIONAL
+ Z_PARAM_ARRAY_HT_OR_LONG(op_ht, op_long)
+ Z_PARAM_BOOL(add_empty)
+ ZEND_PARSE_PARAMETERS_END();
+
+ if (!op_ht && !PHP_FILTER_ID_EXISTS(op_long)) {
+ php_error_docref(NULL, E_WARNING, "Unknown filter with ID " ZEND_LONG_FMT, op_long);
RETURN_FALSE;
}
- php_filter_array_handler(array_input, op, return_value, add_empty);
+ php_filter_array_handler(array_input, op_ht, op_long, return_value, add_empty);
}
/* }}} */
diff --git a/ext/filter/filter.stub.php b/ext/filter/filter.stub.php
index e8e6b0fbdd..56f926b913 100644
--- a/ext/filter/filter.stub.php
+++ b/ext/filter/filter.stub.php
@@ -4,17 +4,13 @@
function filter_has_var(int $type, string $variable_name): bool {}
-/** @param array|int $options */
-function filter_input(int $type, string $variable_name, int $filter = FILTER_DEFAULT, $options = null): mixed {}
+function filter_input(int $type, string $variable_name, int $filter = FILTER_DEFAULT, array|int $options = 0): mixed {}
-/** @param array|int $options */
-function filter_var(mixed $variable, int $filter = FILTER_DEFAULT, $options = null): mixed {}
+function filter_var(mixed $variable, int $filter = FILTER_DEFAULT, array|int $options = 0): mixed {}
-/** @param array|int $options */
-function filter_input_array(int $type, $options = FILTER_DEFAULT, bool $add_empty = true): array|false|null {}
+function filter_input_array(int $type, array|int $options = FILTER_DEFAULT, bool $add_empty = true): array|false|null {}
-/** @param array|int $options */
-function filter_var_array(array $data, $options = FILTER_DEFAULT, bool $add_empty = true): array|false|null {}
+function filter_var_array(array $data, array|int $options = FILTER_DEFAULT, bool $add_empty = true): array|false|null {}
function filter_list(): array {}
diff --git a/ext/filter/filter_arginfo.h b/ext/filter/filter_arginfo.h
index 00d1809250..bb3ab54666 100644
--- a/ext/filter/filter_arginfo.h
+++ b/ext/filter/filter_arginfo.h
@@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
- * Stub hash: 54d4bb809e05c73a1a16174bce578377f7cd8f31 */
+ * Stub hash: dae0cf8beeb47a996123cffd3b429482047d42c1 */
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_filter_has_var, 0, 2, _IS_BOOL, 0)
ZEND_ARG_TYPE_INFO(0, type, IS_LONG, 0)
@@ -10,24 +10,24 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_filter_input, 0, 2, IS_MIXED, 0)
ZEND_ARG_TYPE_INFO(0, type, IS_LONG, 0)
ZEND_ARG_TYPE_INFO(0, variable_name, IS_STRING, 0)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, filter, IS_LONG, 0, "FILTER_DEFAULT")
- ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, options, "null")
+ ZEND_ARG_TYPE_MASK(0, options, MAY_BE_ARRAY|MAY_BE_LONG, "0")
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_filter_var, 0, 1, IS_MIXED, 0)
ZEND_ARG_TYPE_INFO(0, variable, IS_MIXED, 0)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, filter, IS_LONG, 0, "FILTER_DEFAULT")
- ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, options, "null")
+ ZEND_ARG_TYPE_MASK(0, options, MAY_BE_ARRAY|MAY_BE_LONG, "0")
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_filter_input_array, 0, 1, MAY_BE_ARRAY|MAY_BE_FALSE|MAY_BE_NULL)
ZEND_ARG_TYPE_INFO(0, type, IS_LONG, 0)
- ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, options, "FILTER_DEFAULT")
+ ZEND_ARG_TYPE_MASK(0, options, MAY_BE_ARRAY|MAY_BE_LONG, "FILTER_DEFAULT")
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, add_empty, _IS_BOOL, 0, "true")
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_filter_var_array, 0, 1, MAY_BE_ARRAY|MAY_BE_FALSE|MAY_BE_NULL)
ZEND_ARG_TYPE_INFO(0, data, IS_ARRAY, 0)
- ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, options, "FILTER_DEFAULT")
+ ZEND_ARG_TYPE_MASK(0, options, MAY_BE_ARRAY|MAY_BE_LONG, "FILTER_DEFAULT")
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, add_empty, _IS_BOOL, 0, "true")
ZEND_END_ARG_INFO()
diff --git a/ext/filter/tests/010.phpt b/ext/filter/tests/010.phpt
index 46b6044668..802f817e98 100644
--- a/ext/filter/tests/010.phpt
+++ b/ext/filter/tests/010.phpt
@@ -17,7 +17,7 @@ var_dump(filter_var(1, 0, array()));
echo "Done\n";
?>
---EXPECT--
+--EXPECTF--
array(7) {
[0]=>
int(1)
@@ -55,6 +55,10 @@ array(7) {
string(1) "1"
string(1) "1"
string(1) "1"
+
+Warning: filter_var(): Unknown filter with ID -1 in %s on line %d
bool(false)
+
+Warning: filter_var(): Unknown filter with ID 0 in %s on line %d
bool(false)
Done
diff --git a/ext/filter/tests/011.phpt b/ext/filter/tests/011.phpt
index 1b2a2ec357..5c00f895fd 100644
--- a/ext/filter/tests/011.phpt
+++ b/ext/filter/tests/011.phpt
@@ -14,7 +14,11 @@ ini_set('html_errors', false);
var_dump(filter_input(INPUT_GET, "a", FILTER_SANITIZE_STRIPPED));
var_dump(filter_input(INPUT_GET, "b", FILTER_SANITIZE_URL));
var_dump(filter_input(INPUT_GET, "a", FILTER_SANITIZE_SPECIAL_CHARS, array(1,2,3,4,5)));
-var_dump(filter_input(INPUT_GET, "b", FILTER_VALIDATE_FLOAT, new stdClass));
+try {
+ filter_input(INPUT_GET, "b", FILTER_VALIDATE_FLOAT, new stdClass);
+} catch (TypeError $exception) {
+ echo $exception->getMessage() . "\n";
+}
var_dump(filter_input(INPUT_POST, "c", FILTER_SANITIZE_STRIPPED, array(5,6,7,8)));
var_dump(filter_input(INPUT_POST, "d", FILTER_VALIDATE_FLOAT));
var_dump(filter_input(INPUT_POST, "c", FILTER_SANITIZE_SPECIAL_CHARS));
@@ -22,13 +26,11 @@ var_dump(filter_input(INPUT_POST, "d", FILTER_VALIDATE_INT));
echo "Done\n";
?>
---EXPECTF--
+--EXPECT--
string(4) "test"
string(18) "http://example.com"
string(27) "&#60;b&#62;test&#60;/b&#62;"
-
-Notice: Object of class stdClass could not be converted to int in %s011.php on line %d
-bool(false)
+filter_input(): Argument #4 ($options) must be of type array|int, stdClass given
string(6) "string"
float(12345.7)
string(29) "&#60;p&#62;string&#60;/p&#62;"
diff --git a/ext/filter/tests/039.phpt b/ext/filter/tests/039.phpt
index f5a1cf2fe7..ec6f075bc3 100644
--- a/ext/filter/tests/039.phpt
+++ b/ext/filter/tests/039.phpt
@@ -10,20 +10,41 @@ var_dump(filter_var_array(array()));
var_dump(filter_var_array(array(1,"blah"=>"hoho")));
var_dump(filter_var_array(array(), -1));
var_dump(filter_var_array(array(), 1000000));
-var_dump(filter_var_array(array(), ""));
+
+try {
+ filter_var_array(array(), "");
+} catch (TypeError $exception) {
+ echo $exception->getMessage() . "\n";
+}
echo "-- (2)\n";
var_dump(filter_var_array(array(""=>""), -1));
var_dump(filter_var_array(array(""=>""), 1000000));
-var_dump(filter_var_array(array(""=>""), ""));
+
+try {
+ filter_var_array(array(""=>""), "");
+} catch (TypeError $exception) {
+ echo $exception->getMessage() . "\n";
+}
echo "-- (3)\n";
var_dump(filter_var_array(array("aaa"=>"bbb"), -1));
var_dump(filter_var_array(array("aaa"=>"bbb"), 1000000));
-var_dump(filter_var_array(array("aaa"=>"bbb"), ""));
+
+try {
+ filter_var_array(array("aaa"=>"bbb"), "");
+} catch (TypeError $exception) {
+ echo $exception->getMessage() . "\n";
+}
echo "-- (4)\n";
-var_dump(filter_var_array(array(), new stdclass));
+
+try {
+ filter_var_array(array(), new stdclass);
+} catch (TypeError $exception) {
+ echo $exception->getMessage() . "\n";
+}
+
var_dump(filter_var_array(array(), array()));
var_dump(filter_var_array(array(), array("var_name"=>1)));
var_dump(filter_var_array(array(), array("var_name"=>-1)));
@@ -50,12 +71,16 @@ var_dump(filter_var_array($a, $b));
var_dump($a, $b);
$a = array(""=>""); $b = "";
-var_dump(filter_var_array($a, $b));
+try {
+ filter_var_array($a, $b);
+} catch (TypeError $exception) {
+ echo $exception->getMessage() . "\n";
+}
var_dump($a, $b);
echo "Done\n";
?>
---EXPECT--
+--EXPECTF--
-- (1)
array(0) {
}
@@ -65,19 +90,31 @@ array(2) {
["blah"]=>
string(4) "hoho"
}
+
+Warning: filter_var_array(): Unknown filter with ID -1 in %s on line %d
bool(false)
+
+Warning: filter_var_array(): Unknown filter with ID 1000000 in %s on line %d
bool(false)
-bool(false)
+filter_var_array(): Argument #2 ($options) must be of type array|int, string given
-- (2)
+
+Warning: filter_var_array(): Unknown filter with ID -1 in %s on line %d
bool(false)
+
+Warning: filter_var_array(): Unknown filter with ID 1000000 in %s on line %d
bool(false)
-bool(false)
+filter_var_array(): Argument #2 ($options) must be of type array|int, string given
-- (3)
+
+Warning: filter_var_array(): Unknown filter with ID -1 in %s on line %d
bool(false)
+
+Warning: filter_var_array(): Unknown filter with ID 1000000 in %s on line %d
bool(false)
-bool(false)
+filter_var_array(): Argument #2 ($options) must be of type array|int, string given
-- (4)
-bool(false)
+filter_var_array(): Argument #2 ($options) must be of type array|int, stdClass given
array(0) {
}
array(1) {
@@ -95,19 +132,23 @@ array(1) {
-- (5)
filter_var_array(): Argument #2 ($options) cannot contain empty keys
filter_var_array(): Argument #2 ($options) cannot contain empty keys
+
+Warning: filter_var_array(): Unknown filter with ID -1 in %s on line %d
bool(false)
array(1) {
[""]=>
string(0) ""
}
int(-1)
+
+Warning: filter_var_array(): Unknown filter with ID 100000 in %s on line %d
bool(false)
array(1) {
[""]=>
string(0) ""
}
int(100000)
-bool(false)
+filter_var_array(): Argument #2 ($options) must be of type array|int, string given
array(1) {
[""]=>
string(0) ""
diff --git a/ext/filter/tests/057.phpt b/ext/filter/tests/057.phpt
index fc4c3a824c..7c57a2670b 100644
--- a/ext/filter/tests/057.phpt
+++ b/ext/filter/tests/057.phpt
@@ -5,20 +5,44 @@ filter_input_array() and filter_var_array() with invalid $definition arguments
--FILE--
<?php
foreach (array(null, true, false, 1, "", new stdClass) as $invalid) {
- var_dump(filter_input_array(INPUT_POST, $invalid));
- var_dump(filter_var_array(array(), $invalid));
+ try {
+ var_dump(filter_input_array(INPUT_POST, $invalid));
+ } catch (TypeError $exception) {
+ echo $exception->getMessage() . "\n";
+ }
+
+ try {
+ var_dump(filter_var_array(array(), $invalid));
+ } catch (TypeError $exception) {
+ echo $exception->getMessage() . "\n";
+ }
}
?>
---EXPECT--
-bool(false)
-bool(false)
-bool(false)
-bool(false)
+--EXPECTF--
+Warning: filter_input_array(): Unknown filter with ID 0 in %s on line %d
bool(false)
+
+Warning: filter_var_array(): Unknown filter with ID 0 in %s on line %d
bool(false)
+
+Warning: filter_input_array(): Unknown filter with ID 1 in %s on line %d
bool(false)
+
+Warning: filter_var_array(): Unknown filter with ID 1 in %s on line %d
bool(false)
+
+Warning: filter_input_array(): Unknown filter with ID 0 in %s on line %d
bool(false)
+
+Warning: filter_var_array(): Unknown filter with ID 0 in %s on line %d
bool(false)
+
+Warning: filter_input_array(): Unknown filter with ID 1 in %s on line %d
bool(false)
+
+Warning: filter_var_array(): Unknown filter with ID 1 in %s on line %d
bool(false)
+filter_input_array(): Argument #2 ($options) must be of type array|int, string given
+filter_var_array(): Argument #2 ($options) must be of type array|int, string given
+filter_input_array(): Argument #2 ($options) must be of type array|int, stdClass given
+filter_var_array(): Argument #2 ($options) must be of type array|int, stdClass given
diff --git a/ext/intl/calendar/calendar_class.cpp b/ext/intl/calendar/calendar_class.cpp
index 06f64f5e11..a46ef62e68 100644
--- a/ext/intl/calendar/calendar_class.cpp
+++ b/ext/intl/calendar/calendar_class.cpp
@@ -57,9 +57,9 @@ U_CFUNC void calendar_object_create(zval *object,
calendar_object_construct(object, calendar);
}
-U_CFUNC Calendar *calendar_fetch_native_calendar(zval *object)
+U_CFUNC Calendar *calendar_fetch_native_calendar(zend_object *object)
{
- Calendar_object *co = Z_INTL_CALENDAR_P(object);
+ Calendar_object *co = php_intl_calendar_fetch_object(object);
return co->ucal;
}
diff --git a/ext/intl/calendar/calendar_class.h b/ext/intl/calendar/calendar_class.h
index a4d5236307..c301cda481 100644
--- a/ext/intl/calendar/calendar_class.h
+++ b/ext/intl/calendar/calendar_class.h
@@ -61,14 +61,13 @@ static inline Calendar_object *php_intl_calendar_fetch_object(zend_object *obj)
void calendar_object_create(zval *object, Calendar *calendar);
-Calendar *calendar_fetch_native_calendar(zval *object);
+Calendar *calendar_fetch_native_calendar(zend_object *object);
void calendar_object_construct(zval *object, Calendar *calendar);
void calendar_register_IntlCalendar_class(void);
-extern zend_class_entry *Calendar_ce_ptr,
- *GregorianCalendar_ce_ptr;
+extern zend_class_entry *Calendar_ce_ptr, *GregorianCalendar_ce_ptr;
extern zend_object_handlers Calendar_handlers;
diff --git a/ext/intl/dateformat/dateformat.stub.php b/ext/intl/dateformat/dateformat.stub.php
index 5d77e07555..53cda18560 100644
--- a/ext/intl/dateformat/dateformat.stub.php
+++ b/ext/intl/dateformat/dateformat.stub.php
@@ -12,11 +12,10 @@ class IntlDateFormatter
/**
* @param IntlTimeZone|DateTimeZone|string|null $timezone
- * @param IntlCalendar|int|null $calendar
* @return IntlDateFormatter|null
* @alias datefmt_create
*/
- public static function create(?string $locale, int $datetype, int $timetype, $timezone = null, $calendar = null, string $pattern = "") {}
+ public static function create(?string $locale, int $datetype, int $timetype, $timezone = null, IntlCalendar|int|null $calendar = null, string $pattern = "") {}
/**
* @return int|false
@@ -37,11 +36,10 @@ class IntlDateFormatter
public function getCalendar() {}
/**
- * @param IntlCalendar|int|null $which
* @return bool
* @alias datefmt_set_calendar
*/
- public function setCalendar($which) {}
+ public function setCalendar(IntlCalendar|int|null $which) {}
/**
* @return string|false
diff --git a/ext/intl/dateformat/dateformat_arginfo.h b/ext/intl/dateformat/dateformat_arginfo.h
index d94c886003..7a468d4fda 100644
--- a/ext/intl/dateformat/dateformat_arginfo.h
+++ b/ext/intl/dateformat/dateformat_arginfo.h
@@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
- * Stub hash: 1b018a6b473db965a89c4ce9ebce3133d8d304db */
+ * Stub hash: 6e7935cd23cd9bba625cf65d08d8e3796f938d74 */
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_IntlDateFormatter___construct, 0, 0, 3)
ZEND_ARG_TYPE_INFO(0, locale, IS_STRING, 1)
@@ -10,7 +10,14 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_IntlDateFormatter___construct, 0, 0, 3)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, pattern, IS_STRING, 0, "\"\"")
ZEND_END_ARG_INFO()
-#define arginfo_class_IntlDateFormatter_create arginfo_class_IntlDateFormatter___construct
+ZEND_BEGIN_ARG_INFO_EX(arginfo_class_IntlDateFormatter_create, 0, 0, 3)
+ ZEND_ARG_TYPE_INFO(0, locale, IS_STRING, 1)
+ ZEND_ARG_TYPE_INFO(0, datetype, IS_LONG, 0)
+ ZEND_ARG_TYPE_INFO(0, timetype, IS_LONG, 0)
+ ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, timezone, "null")
+ ZEND_ARG_OBJ_TYPE_MASK(0, calendar, IntlCalendar, MAY_BE_LONG|MAY_BE_NULL, "null")
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, pattern, IS_STRING, 0, "\"\"")
+ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_IntlDateFormatter_getDateType, 0, 0, 0)
ZEND_END_ARG_INFO()
@@ -20,7 +27,7 @@ ZEND_END_ARG_INFO()
#define arginfo_class_IntlDateFormatter_getCalendar arginfo_class_IntlDateFormatter_getDateType
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_IntlDateFormatter_setCalendar, 0, 0, 1)
- ZEND_ARG_INFO(0, which)
+ ZEND_ARG_OBJ_TYPE_MASK(0, which, IntlCalendar, MAY_BE_LONG|MAY_BE_NULL, NULL)
ZEND_END_ARG_INFO()
#define arginfo_class_IntlDateFormatter_getTimeZoneId arginfo_class_IntlDateFormatter_getDateType
diff --git a/ext/intl/dateformat/dateformat_attrcpp.cpp b/ext/intl/dateformat/dateformat_attrcpp.cpp
index fdf61d8500..343ef170d2 100644
--- a/ext/intl/dateformat/dateformat_attrcpp.cpp
+++ b/ext/intl/dateformat/dateformat_attrcpp.cpp
@@ -156,12 +156,22 @@ U_CFUNC PHP_FUNCTION(datefmt_get_calendar_object)
/* {{{ Set formatter's calendar. */
U_CFUNC PHP_FUNCTION(datefmt_set_calendar)
{
- zval *calendar_zv;
+ zend_object *calendar_obj;
+ zend_long calendar_long;
+ zend_bool calendar_is_null;
DATE_FORMAT_METHOD_INIT_VARS;
- if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Oz",
- &object, IntlDateFormatter_ce_ptr, &calendar_zv) == FAILURE) {
- RETURN_THROWS();
+ object = getThis();
+
+ if (object) {
+ ZEND_PARSE_PARAMETERS_START(1, 1)
+ Z_PARAM_OBJ_OF_CLASS_OR_LONG_OR_NULL(calendar_obj, Calendar_ce_ptr, calendar_long, calendar_is_null)
+ ZEND_PARSE_PARAMETERS_END();
+ } else {
+ ZEND_PARSE_PARAMETERS_START(2, 2)
+ Z_PARAM_OBJECT_OF_CLASS(object, IntlDateFormatter_ce_ptr)
+ Z_PARAM_OBJ_OF_CLASS_OR_LONG_OR_NULL(calendar_obj, Calendar_ce_ptr, calendar_long, calendar_is_null)
+ ZEND_PARSE_PARAMETERS_END();
}
DATE_FORMAT_METHOD_FETCH_OBJECT;
@@ -174,9 +184,9 @@ U_CFUNC PHP_FUNCTION(datefmt_set_calendar)
// because we would have lost modifiers such as @calendar. We
// must store the requested locale on object creation
- if (datefmt_process_calendar_arg(calendar_zv, locale,
- "datefmt_set_calendar", INTL_DATA_ERROR_P(dfo), cal, cal_type,
- cal_owned) == FAILURE) {
+ if (datefmt_process_calendar_arg(calendar_obj, calendar_long, calendar_is_null, locale,
+ "datefmt_set_calendar", INTL_DATA_ERROR_P(dfo), cal, cal_type, cal_owned) == FAILURE
+ ) {
RETURN_FALSE;
}
diff --git a/ext/intl/dateformat/dateformat_create.cpp b/ext/intl/dateformat/dateformat_create.cpp
index a75719c0f4..43e113fab1 100644
--- a/ext/intl/dateformat/dateformat_create.cpp
+++ b/ext/intl/dateformat/dateformat_create.cpp
@@ -26,6 +26,8 @@ extern "C" {
#include "php_intl.h"
#include "dateformat_create.h"
#include "dateformat_class.h"
+#define USE_CALENDAR_POINTER 1
+#include "../calendar/calendar_class.h"
#define USE_TIMEZONE_POINTER 1
#include "../timezone/timezone_class.h"
#include "../intl_convert.h"
@@ -43,16 +45,18 @@ extern "C" {
UDAT_PATTERN == (i))
/* {{{ */
-static int datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS)
+static zend_result datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS)
{
zval *object;
- const char *locale_str;
+ char *locale_str;
size_t locale_len = 0;
Locale locale;
zend_long date_type = 0;
zend_long time_type = 0;
- zval *calendar_zv = NULL;
- Calendar *calendar = NULL;
+ zend_object *calendar_obj = NULL;
+ zend_long calendar_long;
+ zend_bool calendar_is_null = 1;
+ Calendar *cal = NULL;
zend_long calendar_type;
bool calendar_owned;
zval *timezone_zv = NULL;
@@ -66,18 +70,21 @@ static int datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS)
intl_error_reset(NULL);
object = return_value;
- /* Parse parameters. */
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "s!ll|zzs",
- &locale_str, &locale_len, &date_type, &time_type, &timezone_zv,
- &calendar_zv, &pattern_str, &pattern_str_len) == FAILURE) {
- return FAILURE;
- }
+
+ ZEND_PARSE_PARAMETERS_START(3, 6)
+ Z_PARAM_STRING_OR_NULL(locale_str, locale_len)
+ Z_PARAM_LONG(date_type)
+ Z_PARAM_LONG(time_type)
+ Z_PARAM_OPTIONAL
+ Z_PARAM_ZVAL(timezone_zv)
+ Z_PARAM_OBJ_OF_CLASS_OR_LONG_OR_NULL(calendar_obj, Calendar_ce_ptr, calendar_long, calendar_is_null)
+ Z_PARAM_STRING_OR_NULL(pattern_str, pattern_str_len)
+ ZEND_PARSE_PARAMETERS_END_EX(return FAILURE);
DATE_FORMAT_METHOD_FETCH_OBJECT_NO_CHECK;
if (DATE_FORMAT_OBJECT(dfo) != NULL) {
- intl_errors_set(INTL_DATA_ERROR_P(dfo), U_ILLEGAL_ARGUMENT_ERROR,
- "datefmt_create: cannot call constructor twice", 0);
+ intl_errors_set(INTL_DATA_ERROR_P(dfo), U_ILLEGAL_ARGUMENT_ERROR, "datefmt_create: cannot call constructor twice", 0);
return FAILURE;
}
@@ -87,20 +94,19 @@ static int datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS)
}
if (!INTL_UDATE_FMT_OK(time_type)) {
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_create: invalid time format style", 0);
- return FAILURE;
+return FAILURE;
}
INTL_CHECK_LOCALE_LEN_OR_FAILURE(locale_len);
if (locale_len == 0) {
- locale_str = intl_locale_get_default();
+ locale_str = (char *) intl_locale_get_default();
}
locale = Locale::createFromName(locale_str);
/* process calendar */
- if (datefmt_process_calendar_arg(calendar_zv, locale, "datefmt_create",
- INTL_DATA_ERROR_P(dfo), calendar, calendar_type,
- calendar_owned)
- == FAILURE) {
+ if (datefmt_process_calendar_arg(calendar_obj, calendar_long, calendar_is_null, locale, "datefmt_create",
+ INTL_DATA_ERROR_P(dfo), cal, calendar_type, calendar_owned) == FAILURE
+ ) {
goto error;
}
@@ -143,10 +149,10 @@ static int datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS)
if (!U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) {
DateFormat *df = (DateFormat*)DATE_FORMAT_OBJECT(dfo);
if (calendar_owned) {
- df->adoptCalendar(calendar);
+ df->adoptCalendar(cal);
calendar_owned = false;
} else {
- df->setCalendar(*calendar);
+ df->setCalendar(*cal);
}
if (timezone != NULL) {
@@ -171,8 +177,8 @@ error:
if (timezone != NULL && DATE_FORMAT_OBJECT(dfo) == NULL) {
delete timezone;
}
- if (calendar != NULL && calendar_owned) {
- delete calendar;
+ if (cal != NULL && calendar_owned) {
+ delete cal;
}
return U_FAILURE(intl_error_get_code(NULL)) ? FAILURE : SUCCESS;
@@ -183,7 +189,7 @@ error:
U_CFUNC PHP_FUNCTION( datefmt_create )
{
object_init_ex( return_value, IntlDateFormatter_ce_ptr );
- if (datefmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) {
+ if (datefmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) {
zval_ptr_dtor(return_value);
RETURN_NULL();
}
diff --git a/ext/intl/dateformat/dateformat_format_object.cpp b/ext/intl/dateformat/dateformat_format_object.cpp
index 9723006b15..d569eb935d 100644
--- a/ext/intl/dateformat/dateformat_format_object.cpp
+++ b/ext/intl/dateformat/dateformat_format_object.cpp
@@ -158,7 +158,7 @@ U_CFUNC PHP_FUNCTION(datefmt_format_object)
zend_class_entry *instance_ce = Z_OBJCE_P(object);
if (instanceof_function(instance_ce, Calendar_ce_ptr)) {
- Calendar *obj_cal = calendar_fetch_native_calendar(object);
+ Calendar *obj_cal = calendar_fetch_native_calendar(Z_OBJ_P(object));
if (obj_cal == NULL) {
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
"datefmt_format_object: bad IntlCalendar instance: "
diff --git a/ext/intl/dateformat/dateformat_helpers.cpp b/ext/intl/dateformat/dateformat_helpers.cpp
index 69332e931c..46c909bf95 100644
--- a/ext/intl/dateformat/dateformat_helpers.cpp
+++ b/ext/intl/dateformat/dateformat_helpers.cpp
@@ -28,28 +28,22 @@ extern "C" {
using icu::GregorianCalendar;
-int datefmt_process_calendar_arg(zval* calendar_zv,
- Locale const& locale,
- const char *func_name,
- intl_error *err,
- Calendar*& cal,
- zend_long& cal_int_type,
- bool& calendar_owned)
-{
+int datefmt_process_calendar_arg(
+ zend_object *calendar_obj, zend_long calendar_long, zend_bool calendar_is_null, Locale const& locale,
+ const char *func_name, intl_error *err, Calendar*& cal, zend_long& cal_int_type, bool& calendar_owned
+) {
char *msg;
UErrorCode status = UErrorCode();
- if (calendar_zv == NULL || Z_TYPE_P(calendar_zv) == IS_NULL) {
-
+ if (calendar_is_null) {
// default requested
cal = new GregorianCalendar(locale, status);
calendar_owned = true;
cal_int_type = UCAL_GREGORIAN;
- } else if (Z_TYPE_P(calendar_zv) == IS_LONG) {
-
- zend_long v = Z_LVAL_P(calendar_zv);
+ } else if (!calendar_obj) {
+ zend_long v = calendar_long;
if (v != (zend_long)UCAL_TRADITIONAL && v != (zend_long)UCAL_GREGORIAN) {
spprintf(&msg, 0, "%s: Invalid value for calendar type; it must be "
"one of IntlDateFormatter::TRADITIONAL (locale's default "
@@ -66,12 +60,10 @@ int datefmt_process_calendar_arg(zval* calendar_zv,
}
calendar_owned = true;
- cal_int_type = Z_LVAL_P(calendar_zv);
-
- } else if (Z_TYPE_P(calendar_zv) == IS_OBJECT &&
- instanceof_function(Z_OBJCE_P(calendar_zv), Calendar_ce_ptr)) {
+ cal_int_type = calendar_long;
- cal = calendar_fetch_native_calendar(calendar_zv);
+ } else if (calendar_obj) {
+ cal = calendar_fetch_native_calendar(calendar_obj);
if (cal == NULL) {
spprintf(&msg, 0, "%s: Found unconstructed IntlCalendar object",
func_name);
diff --git a/ext/intl/dateformat/dateformat_helpers.h b/ext/intl/dateformat/dateformat_helpers.h
index 0c88977015..1f2d7eb32e 100644
--- a/ext/intl/dateformat/dateformat_helpers.h
+++ b/ext/intl/dateformat/dateformat_helpers.h
@@ -30,12 +30,9 @@ using icu::Locale;
using icu::Calendar;
using icu::DateFormat;
-int datefmt_process_calendar_arg(zval* calendar_zv,
- Locale const& locale,
- const char *func_name,
- intl_error *err,
- Calendar*& cal,
- zend_long& cal_int_type,
- bool& calendar_owned);
+int datefmt_process_calendar_arg(
+ zend_object *calendar_obj, zend_long calendar_long, zend_bool calendar_is_null, Locale const& locale,
+ const char *func_name, intl_error *err, Calendar*& cal, zend_long& cal_int_type, bool& calendar_owned
+);
#endif /* DATEFORMAT_HELPERS_H */
diff --git a/ext/intl/php_intl.stub.php b/ext/intl/php_intl.stub.php
index 7662004f30..f2a1af1c2e 100644
--- a/ext/intl/php_intl.stub.php
+++ b/ext/intl/php_intl.stub.php
@@ -153,11 +153,8 @@ function intl_error_name(int $error_code): string {}
/* dateformat */
-/**
- * @param IntlTimeZone|DateTimeZone|string|null $timezone
- * @param IntlCalendar|int|null $calendar
- */
-function datefmt_create(?string $locale, int $datetype, int $timetype, $timezone = null, $calendar = null, string $pattern = ""): ?IntlDateFormatter {}
+/** @param IntlTimeZone|DateTimeZone|string|null $timezone */
+function datefmt_create(?string $locale, int $datetype, int $timetype, $timezone = null, IntlCalendar|int|null $calendar = null, string $pattern = ""): ?IntlDateFormatter {}
function datefmt_get_datetype(IntlDateFormatter $df): int|false {}
@@ -165,8 +162,7 @@ function datefmt_get_timetype(IntlDateFormatter $df): int|false {}
function datefmt_get_calendar(IntlDateFormatter $df): int|false {}
-/** @param IntlCalendar|int|null $which */
-function datefmt_set_calendar(IntlDateFormatter $df, $which): bool {}
+function datefmt_set_calendar(IntlDateFormatter $df, IntlCalendar|int|null $which): bool {}
function datefmt_get_timezone_id(IntlDateFormatter $df): string|false {}
diff --git a/ext/intl/php_intl_arginfo.h b/ext/intl/php_intl_arginfo.h
index 3917187a5c..32f098d0bb 100644
--- a/ext/intl/php_intl_arginfo.h
+++ b/ext/intl/php_intl_arginfo.h
@@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
- * Stub hash: fdc7c500ddc5bc560ec54b7ce12d5961a4697a63 */
+ * Stub hash: 324b7ae3eaab4777117c1c6963bc841088e6b998 */
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_intlcal_create_instance, 0, 0, IntlCalendar, 1)
ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, timeZone, "null")
@@ -281,7 +281,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_datefmt_create, 0, 3, IntlDateFor
ZEND_ARG_TYPE_INFO(0, datetype, IS_LONG, 0)
ZEND_ARG_TYPE_INFO(0, timetype, IS_LONG, 0)
ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, timezone, "null")
- ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, calendar, "null")
+ ZEND_ARG_OBJ_TYPE_MASK(0, calendar, IntlCalendar, MAY_BE_LONG|MAY_BE_NULL, "null")
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, pattern, IS_STRING, 0, "\"\"")
ZEND_END_ARG_INFO()
@@ -295,7 +295,7 @@ ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_datefmt_set_calendar, 0, 2, _IS_BOOL, 0)
ZEND_ARG_OBJ_INFO(0, df, IntlDateFormatter, 0)
- ZEND_ARG_INFO(0, which)
+ ZEND_ARG_OBJ_TYPE_MASK(0, which, IntlCalendar, MAY_BE_LONG|MAY_BE_NULL, NULL)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_datefmt_get_timezone_id, 0, 1, MAY_BE_STRING|MAY_BE_FALSE)
diff --git a/ext/intl/tests/dateformat___construct_bad_tz_cal.phpt b/ext/intl/tests/dateformat___construct_bad_tz_cal.phpt
index 086bc01340..928c30b922 100644
--- a/ext/intl/tests/dateformat___construct_bad_tz_cal.phpt
+++ b/ext/intl/tests/dateformat___construct_bad_tz_cal.phpt
@@ -26,7 +26,7 @@ try {
}
try {
var_dump(new IntlDateFormatter(NULL, 0, 0, NULL, new stdclass));
-} catch (IntlException $e) {
+} catch (TypeError $e) {
print_exception($e);
}
?>
@@ -35,4 +35,4 @@ Exception: IntlDateFormatter::__construct(): datefmt_create: No such time zone:
Exception: IntlDateFormatter::__construct(): datefmt_create: Invalid value for calendar type; it must be one of IntlDateFormatter::TRADITIONAL (locale's default calendar) or IntlDateFormatter::GREGORIAN. Alternatively, it can be an IntlCalendar object in %s on line %d
-Exception: IntlDateFormatter::__construct(): datefmt_create: Invalid calendar argument; should be an integer or an IntlCalendar instance in %s on line %d
+Exception: IntlDateFormatter::__construct(): Argument #5 ($calendar) must be of type IntlCalendar|int|null, stdClass given in %s on line %d
diff --git a/ext/session/session.c b/ext/session/session.c
index 4f12e447ba..79b82f90f7 100644
--- a/ext/session/session.c
+++ b/ext/session/session.c
@@ -1674,7 +1674,8 @@ PHPAPI void session_adapt_url(const char *url, size_t url_len, char **new_url, s
Set session cookie parameters */
PHP_FUNCTION(session_set_cookie_params)
{
- zval *lifetime_or_options = NULL;
+ HashTable *options_ht;
+ zend_long lifetime_long;
zend_string *lifetime = NULL, *path = NULL, *domain = NULL, *samesite = NULL;
zend_bool secure = 0, secure_null = 1;
zend_bool httponly = 0, httponly_null = 1;
@@ -1687,12 +1688,12 @@ PHP_FUNCTION(session_set_cookie_params)
}
ZEND_PARSE_PARAMETERS_START(1, 5)
- Z_PARAM_ZVAL(lifetime_or_options)
+ Z_PARAM_ARRAY_HT_OR_LONG(options_ht, lifetime_long)
Z_PARAM_OPTIONAL
- Z_PARAM_STR(path)
- Z_PARAM_STR(domain)
- Z_PARAM_BOOL_EX(secure, secure_null, 1, 0)
- Z_PARAM_BOOL_EX(httponly, httponly_null, 1, 0)
+ Z_PARAM_STR_OR_NULL(path)
+ Z_PARAM_STR_OR_NULL(domain)
+ Z_PARAM_BOOL_OR_NULL(secure, secure_null)
+ Z_PARAM_BOOL_OR_NULL(httponly, httponly_null)
ZEND_PARSE_PARAMETERS_END();
if (PS(session_status) == php_session_active) {
@@ -1705,20 +1706,31 @@ PHP_FUNCTION(session_set_cookie_params)
RETURN_FALSE;
}
- if (Z_TYPE_P(lifetime_or_options) == IS_ARRAY) {
+ if (options_ht) {
zend_string *key;
zval *value;
if (path) {
- path = NULL;
- domain = NULL;
- secure_null = 1;
- httponly_null = 1;
- php_error_docref(NULL, E_WARNING, "Cannot pass arguments after the options array");
- RETURN_FALSE;
+ zend_argument_value_error(2, "must be null when argument #1 ($lifetime_or_options) is an array");
+ RETURN_THROWS();
+ }
+
+ if (domain) {
+ zend_argument_value_error(3, "must be null when argument #1 ($lifetime_or_options) is an array");
+ RETURN_THROWS();
+ }
+
+ if (!secure_null) {
+ zend_argument_value_error(4, "must be null when argument #1 ($lifetime_or_options) is an array");
+ RETURN_THROWS();
+ }
+
+ if (!httponly_null) {
+ zend_argument_value_error(5, "must be null when argument #1 ($lifetime_or_options) is an array");
+ RETURN_THROWS();
}
- ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(lifetime_or_options), key, value) {
+ ZEND_HASH_FOREACH_STR_KEY_VAL(options_ht, key, value) {
if (key) {
ZVAL_DEREF(value);
if(!strcasecmp("lifetime", ZSTR_VAL(key))) {
@@ -1754,7 +1766,7 @@ PHP_FUNCTION(session_set_cookie_params)
RETURN_THROWS();
}
} else {
- lifetime = zval_get_string(lifetime_or_options);
+ lifetime = zend_long_to_str(lifetime_long);
}
/* Exception during string conversion */
diff --git a/ext/session/session.stub.php b/ext/session/session.stub.php
index b8f9f33eba..36a0b983b9 100644
--- a/ext/session/session.stub.php
+++ b/ext/session/session.stub.php
@@ -49,8 +49,7 @@ function session_cache_limiter(?string $cache_limiter = null): string|false {}
function session_cache_expire(?int $new_cache_expire = null): int|false {}
-/** @param int|array $lifetime_or_options */
-function session_set_cookie_params($lifetime_or_options, string $path = UNKNOWN, string $domain = "", ?bool $secure = null, ?bool $httponly = null): bool {}
+function session_set_cookie_params(array|int $lifetime_or_options, ?string $path = null, ?string $domain = null, ?bool $secure = null, ?bool $httponly = null): bool {}
function session_start(array $options = []): bool {}
diff --git a/ext/session/session_arginfo.h b/ext/session/session_arginfo.h
index c47dee6315..f29a0df86b 100644
--- a/ext/session/session_arginfo.h
+++ b/ext/session/session_arginfo.h
@@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
- * Stub hash: 22b829d3cdd092c393c924f323cd19bea1517579 */
+ * Stub hash: 9bdf602c14822b13553a5214a415e312c21cd30c */
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_session_name, 0, 0, MAY_BE_STRING|MAY_BE_FALSE)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, name, IS_STRING, 1, "null")
@@ -78,9 +78,9 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_session_cache_expire, 0, 0, MAY_
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_session_set_cookie_params, 0, 1, _IS_BOOL, 0)
- ZEND_ARG_INFO(0, lifetime_or_options)
- ZEND_ARG_TYPE_INFO(0, path, IS_STRING, 0)
- ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, domain, IS_STRING, 0, "\"\"")
+ ZEND_ARG_TYPE_MASK(0, lifetime_or_options, MAY_BE_ARRAY|MAY_BE_LONG, NULL)
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, path, IS_STRING, 1, "null")
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, domain, IS_STRING, 1, "null")
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, secure, _IS_BOOL, 1, "null")
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, httponly, _IS_BOOL, 1, "null")
ZEND_END_ARG_INFO()
diff --git a/ext/session/tests/session_set_cookie_params_variation7.phpt b/ext/session/tests/session_set_cookie_params_variation7.phpt
index 25feabf1fd..cdc56554e3 100644
--- a/ext/session/tests/session_set_cookie_params_variation7.phpt
+++ b/ext/session/tests/session_set_cookie_params_variation7.phpt
@@ -40,7 +40,13 @@ var_dump(session_set_cookie_params(["lifetime" => 42]));
var_dump(ini_get("session.cookie_lifetime"));
var_dump(ini_get("session.cookie_path"));
-var_dump(session_set_cookie_params(["path" => "newpath/"], "arg after options array"));
+
+try {
+ session_set_cookie_params(["path" => "newpath/"], "arg after options array");
+} catch (ValueError $exception) {
+ echo $exception->getMessage() . "\n";
+}
+
var_dump(ini_get("session.cookie_path"));
echo "Done";
@@ -63,8 +69,6 @@ string(1) "0"
bool(true)
string(2) "42"
string(1) "/"
-
-Warning: session_set_cookie_params(): Cannot pass arguments after the options array in %s on line %d
-bool(false)
+session_set_cookie_params(): Argument #2 ($path) must be null when argument #1 ($lifetime_or_options) is an array
string(1) "/"
Done
diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php
index 8e3996e072..281d8167b8 100755
--- a/ext/standard/basic_functions.stub.php
+++ b/ext/standard/basic_functions.stub.php
@@ -502,11 +502,9 @@ function header(string $string, bool $replace = true, int $http_response_code =
function header_remove(?string $name = null): void {}
-/** @param array|int $expires_or_options */
-function setrawcookie(string $name, string $value = '', $expires_or_options = 0, string $path = '', string $domain = '', bool $secure = false, bool $httponly = false): bool {}
+function setrawcookie(string $name, string $value = '', array|int $expires_or_options = 0, string $path = '', string $domain = '', bool $secure = false, bool $httponly = false): bool {}
-/** @param array|int $expires_or_options */
-function setcookie(string $name, string $value = '', $expires_or_options = 0, string $path = '', string $domain = '', bool $secure = false, bool $httponly = false): bool {}
+function setcookie(string $name, string $value = '', array|int $expires_or_options = 0, string $path = '', string $domain = '', bool $secure = false, bool $httponly = false): bool {}
function http_response_code(int $response_code = 0): int|bool {}
@@ -612,11 +610,7 @@ function chunk_split(string $str, int $chunklen = 76, string $ending = "\r\n"):
function substr(string $str, int $start, ?int $length = null): string|false {}
-/**
- * @param array|int $start
- * @param array|int|null $length
- */
-function substr_replace(array|string $str, string|array $replace, $start, $length = null): string|array|false {}
+function substr_replace(array|string $str, array|string $replace, array|int $start, array|int|null $length = null): string|array|false {}
function quotemeta(string $str): string {}
diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h
index 5943429517..5097ca53fc 100755
--- a/ext/standard/basic_functions_arginfo.h
+++ b/ext/standard/basic_functions_arginfo.h
@@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
- * Stub hash: 251fc9f272492ab76c4a1a1dabcd768269cf1bde */
+ * Stub hash: d1bcbdfe71bdc57680abe391d1ef2859538615c2 */
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_set_time_limit, 0, 1, _IS_BOOL, 0)
ZEND_ARG_TYPE_INFO(0, seconds, IS_LONG, 0)
@@ -746,7 +746,7 @@ ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_setrawcookie, 0, 1, _IS_BOOL, 0)
ZEND_ARG_TYPE_INFO(0, name, IS_STRING, 0)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, value, IS_STRING, 0, "\'\'")
- ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, expires_or_options, "0")
+ ZEND_ARG_TYPE_MASK(0, expires_or_options, MAY_BE_ARRAY|MAY_BE_LONG, "0")
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, path, IS_STRING, 0, "\'\'")
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, domain, IS_STRING, 0, "\'\'")
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, secure, _IS_BOOL, 0, "false")
@@ -935,9 +935,9 @@ ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_substr_replace, 0, 3, MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_FALSE)
ZEND_ARG_TYPE_MASK(0, str, MAY_BE_ARRAY|MAY_BE_STRING, NULL)
- ZEND_ARG_TYPE_MASK(0, replace, MAY_BE_STRING|MAY_BE_ARRAY, NULL)
- ZEND_ARG_INFO(0, start)
- ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, length, "null")
+ ZEND_ARG_TYPE_MASK(0, replace, MAY_BE_ARRAY|MAY_BE_STRING, NULL)
+ ZEND_ARG_TYPE_MASK(0, start, MAY_BE_ARRAY|MAY_BE_LONG, NULL)
+ ZEND_ARG_TYPE_MASK(0, length, MAY_BE_ARRAY|MAY_BE_LONG|MAY_BE_NULL, "null")
ZEND_END_ARG_INFO()
#define arginfo_quotemeta arginfo_base64_encode
diff --git a/ext/standard/head.c b/ext/standard/head.c
index 18cb0c4f62..36f64fcb4d 100644
--- a/ext/standard/head.c
+++ b/ext/standard/head.c
@@ -192,13 +192,13 @@ PHPAPI zend_result php_setcookie(zend_string *name, zend_string *value, time_t e
return result;
}
-static zend_result php_head_parse_cookie_options_array(zval *options, zend_long *expires, zend_string **path,
+static zend_result php_head_parse_cookie_options_array(HashTable *options, zend_long *expires, zend_string **path,
zend_string **domain, zend_bool *secure, zend_bool *httponly, zend_string **samesite)
{
zend_string *key;
zval *value;
- ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(options), key, value) {
+ ZEND_HASH_FOREACH_STR_KEY_VAL(options, key, value) {
if (!key) {
zend_value_error("%s(): option array cannot have numeric keys", get_active_function_name());
return FAILURE;
@@ -225,36 +225,33 @@ static zend_result php_head_parse_cookie_options_array(zval *options, zend_long
static void php_setcookie_common(INTERNAL_FUNCTION_PARAMETERS, bool is_raw)
{
- /* to handle overloaded function array|int */
- zval *expires_or_options = NULL;
- zend_string *name, *value = NULL, *path = NULL, *domain = NULL, *samesite = NULL;
+ HashTable *options = NULL;
zend_long expires = 0;
+ zend_string *name, *value = NULL, *path = NULL, *domain = NULL, *samesite = NULL;
zend_bool secure = 0, httponly = 0;
ZEND_PARSE_PARAMETERS_START(1, 7)
Z_PARAM_STR(name)
Z_PARAM_OPTIONAL
Z_PARAM_STR(value)
- Z_PARAM_ZVAL(expires_or_options)
+ Z_PARAM_ARRAY_HT_OR_LONG(options, expires)
Z_PARAM_STR(path)
Z_PARAM_STR(domain)
Z_PARAM_BOOL(secure)
Z_PARAM_BOOL(httponly)
ZEND_PARSE_PARAMETERS_END();
- if (expires_or_options) {
- if (Z_TYPE_P(expires_or_options) == IS_ARRAY) {
- if (UNEXPECTED(ZEND_NUM_ARGS() > 3)) {
- zend_argument_count_error("%s(): Expects exactly 3 arguments when argument #3 "
- "($expires_or_options) is an array", get_active_function_name());
- RETURN_THROWS();
- }
- if (FAILURE == php_head_parse_cookie_options_array(expires_or_options, &expires, &path,
- &domain, &secure, &httponly, &samesite)) {
- goto cleanup;
- }
- } else {
- expires = zval_get_long(expires_or_options);
+ if (options) {
+ if (UNEXPECTED(ZEND_NUM_ARGS() > 3)) {
+ zend_argument_count_error("%s(): Expects exactly 3 arguments when argument #3 "
+ "($expires_or_options) is an array", get_active_function_name());
+ RETURN_THROWS();
+ }
+
+ if (FAILURE == php_head_parse_cookie_options_array(options, &expires, &path,
+ &domain, &secure, &httponly, &samesite)
+ ) {
+ goto cleanup;
}
}
@@ -264,7 +261,7 @@ static void php_setcookie_common(INTERNAL_FUNCTION_PARAMETERS, bool is_raw)
RETVAL_FALSE;
}
- if (expires_or_options && Z_TYPE_P(expires_or_options) == IS_ARRAY) {
+ if (options) {
cleanup:
if (path) {
zend_string_release(path);
diff --git a/ext/standard/string.c b/ext/standard/string.c
index 9fd7e5f454..b3d357baa8 100644
--- a/ext/standard/string.c
+++ b/ext/standard/string.c
@@ -2237,8 +2237,11 @@ PHP_FUNCTION(substr_replace)
{
zend_string *str, *repl_str;
HashTable *str_ht, *repl_ht;
- zval *from;
- zval *len = NULL;
+ HashTable *from_ht;
+ zend_long from_long;
+ HashTable *len_ht = NULL;
+ zend_long len_long;
+ zend_bool len_is_null = 1;
zend_long l = 0;
zend_long f;
zend_string *result;
@@ -2248,39 +2251,26 @@ PHP_FUNCTION(substr_replace)
ZEND_PARSE_PARAMETERS_START(3, 4)
Z_PARAM_ARRAY_HT_OR_STR(str_ht, str)
Z_PARAM_ARRAY_HT_OR_STR(repl_ht, repl_str)
- Z_PARAM_ZVAL(from)
+ Z_PARAM_ARRAY_HT_OR_LONG(from_ht, from_long)
Z_PARAM_OPTIONAL
- Z_PARAM_ZVAL_OR_NULL(len)
+ Z_PARAM_ARRAY_HT_OR_LONG_OR_NULL(len_ht, len_long, len_is_null)
ZEND_PARSE_PARAMETERS_END();
- if (Z_TYPE_P(from) != IS_ARRAY) {
- convert_to_long_ex(from);
- if (EG(exception)) {
- RETURN_THROWS();
- }
- }
-
- if (len) {
- if (Z_TYPE_P(len) != IS_ARRAY) {
- convert_to_long_ex(len);
- l = Z_LVAL_P(len);
- }
- } else {
+ if (len_is_null) {
if (str) {
l = ZSTR_LEN(str);
}
+ } else if (!len_ht) {
+ l = len_long;
}
if (str) {
- if (
- (!len && Z_TYPE_P(from) == IS_ARRAY) ||
- (len && Z_TYPE_P(from) != Z_TYPE_P(len))
- ) {
+ if ((len_is_null && from_ht) || (!len_is_null && (from_ht == NULL) != (len_ht == NULL))) {
php_error_docref(NULL, E_WARNING, "'start' and 'length' should be of same type - numerical or array ");
RETURN_STR_COPY(str);
}
- if (len && Z_TYPE_P(from) == IS_ARRAY) {
- if (zend_hash_num_elements(Z_ARRVAL_P(from)) != zend_hash_num_elements(Z_ARRVAL_P(len))) {
+ if (!len_is_null && from_ht) {
+ if (zend_hash_num_elements(from_ht) != zend_hash_num_elements(len_ht)) {
php_error_docref(NULL, E_WARNING, "'start' and 'length' should have the same number of elements");
RETURN_STR_COPY(str);
}
@@ -2288,8 +2278,8 @@ PHP_FUNCTION(substr_replace)
}
if (str) {
- if (Z_TYPE_P(from) != IS_ARRAY) {
- f = Z_LVAL_P(from);
+ if (!from_ht) {
+ f = from_long;
/* if "from" position is negative, count start position from the end
* of the string
@@ -2364,15 +2354,15 @@ PHP_FUNCTION(substr_replace)
zend_string *tmp_orig_str;
zend_string *orig_str = zval_get_tmp_string(tmp_str, &tmp_orig_str);
- if (Z_TYPE_P(from) == IS_ARRAY) {
- while (from_idx < Z_ARRVAL_P(from)->nNumUsed) {
- tmp_from = &Z_ARRVAL_P(from)->arData[from_idx].val;
+ if (from_ht) {
+ while (from_idx < from_ht->nNumUsed) {
+ tmp_from = &from_ht->arData[from_idx].val;
if (Z_TYPE_P(tmp_from) != IS_UNDEF) {
break;
}
from_idx++;
}
- if (from_idx < Z_ARRVAL_P(from)->nNumUsed) {
+ if (from_idx < from_ht->nNumUsed) {
f = zval_get_long(tmp_from);
if (f < 0) {
@@ -2388,7 +2378,7 @@ PHP_FUNCTION(substr_replace)
f = 0;
}
} else {
- f = Z_LVAL_P(from);
+ f = from_long;
if (f < 0) {
f = (zend_long)ZSTR_LEN(orig_str) + f;
if (f < 0) {
@@ -2399,22 +2389,22 @@ PHP_FUNCTION(substr_replace)
}
}
- if (len && Z_TYPE_P(len) == IS_ARRAY) {
- while (len_idx < Z_ARRVAL_P(len)->nNumUsed) {
- tmp_len = &Z_ARRVAL_P(len)->arData[len_idx].val;
+ if (len_ht) {
+ while (len_idx < len_ht->nNumUsed) {
+ tmp_len = &len_ht->arData[len_idx].val;
if (Z_TYPE_P(tmp_len) != IS_UNDEF) {
break;
}
len_idx++;
}
- if (len_idx < Z_ARRVAL_P(len)->nNumUsed) {
+ if (len_idx < len_ht->nNumUsed) {
l = zval_get_long(tmp_len);
len_idx++;
} else {
l = ZSTR_LEN(orig_str);
}
- } else if (len) {
- l = Z_LVAL_P(len);
+ } else if (!len_is_null) {
+ l = len_long;
} else {
l = ZSTR_LEN(orig_str);
}