Skip to content

Commit 46c0c82

Browse files
kocsismatenikic
andcommitted
Declare array|int and object-of-class|int types in stubs
Closes GH-6081 Co-Authored-By: Nikita Popov <[email protected]>
1 parent 1c81a34 commit 46c0c82

29 files changed

+467
-283
lines changed

Zend/zend_API.c

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -221,15 +221,21 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_error(int error_code,
221221
case ZPP_ERROR_WRONG_CLASS_OR_NULL:
222222
zend_wrong_parameter_class_or_null_error(num, name, arg);
223223
break;
224-
case ZPP_ERROR_WRONG_ARG:
225-
zend_wrong_parameter_type_error(num, expected_type, arg);
226-
break;
227224
case ZPP_ERROR_WRONG_CLASS_OR_STRING:
228225
zend_wrong_parameter_class_or_string_error(num, name, arg);
229226
break;
230227
case ZPP_ERROR_WRONG_CLASS_OR_STRING_OR_NULL:
231228
zend_wrong_parameter_class_or_string_or_null_error(num, name, arg);
232229
break;
230+
case ZPP_ERROR_WRONG_CLASS_OR_LONG:
231+
zend_wrong_parameter_class_or_long_error(num, name, arg);
232+
break;
233+
case ZPP_ERROR_WRONG_CLASS_OR_LONG_OR_NULL:
234+
zend_wrong_parameter_class_or_long_or_null_error(num, name, arg);
235+
break;
236+
case ZPP_ERROR_WRONG_ARG:
237+
zend_wrong_parameter_type_error(num, expected_type, arg);
238+
break;
233239
case ZPP_ERROR_UNEXPECTED_EXTRA_NAMED:
234240
zend_unexpected_extra_named_error();
235241
break;
@@ -280,6 +286,26 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_null_error(u
280286
}
281287
/* }}} */
282288

289+
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_long_error(uint32_t num, const char *name, zval *arg) /* {{{ */
290+
{
291+
if (EG(exception)) {
292+
return;
293+
}
294+
295+
zend_argument_type_error(num, "must be of type %s|int, %s given", name, zend_zval_type_name(arg));
296+
}
297+
/* }}} */
298+
299+
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_long_or_null_error(uint32_t num, const char *name, zval *arg) /* {{{ */
300+
{
301+
if (EG(exception)) {
302+
return;
303+
}
304+
305+
zend_argument_type_error(num, "must be of type %s|int|null, %s given", name, zend_zval_type_name(arg));
306+
}
307+
/* }}} */
308+
283309
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_string_error(uint32_t num, const char *name, zval *arg) /* {{{ */
284310
{
285311
if (EG(exception)) {

Zend/zend_API.h

Lines changed: 72 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1209,6 +1209,8 @@ static zend_always_inline zval *zend_try_array_init(zval *zv)
12091209
_(Z_EXPECTED_STRING_OR_NULL, "of type ?string") \
12101210
_(Z_EXPECTED_ARRAY, "of type array") \
12111211
_(Z_EXPECTED_ARRAY_OR_NULL, "of type ?array") \
1212+
_(Z_EXPECTED_ARRAY_OR_LONG, "of type array|int") \
1213+
_(Z_EXPECTED_ARRAY_OR_LONG_OR_NULL, "of type array|int|null") \
12121214
_(Z_EXPECTED_ITERABLE, "of type iterable") \
12131215
_(Z_EXPECTED_ITERABLE_OR_NULL, "of type ?iterable") \
12141216
_(Z_EXPECTED_FUNC, "a valid callback") \
@@ -1248,6 +1250,8 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_error(int error_code,
12481250
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_type_error(uint32_t num, zend_expected_type expected_type, zval *arg);
12491251
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_error(uint32_t num, const char *name, zval *arg);
12501252
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_null_error(uint32_t num, const char *name, zval *arg);
1253+
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_long_error(uint32_t num, const char *name, zval *arg);
1254+
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_long_or_null_error(uint32_t num, const char *name, zval *arg);
12511255
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_string_error(uint32_t num, const char *name, zval *arg);
12521256
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_string_or_null_error(uint32_t num, const char *name, zval *arg);
12531257
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 *
12611265
#define ZPP_ERROR_WRONG_CALLBACK 2
12621266
#define ZPP_ERROR_WRONG_CLASS 3
12631267
#define ZPP_ERROR_WRONG_CLASS_OR_NULL 4
1264-
#define ZPP_ERROR_WRONG_ARG 5
1265-
#define ZPP_ERROR_WRONG_COUNT 6
1266-
#define ZPP_ERROR_WRONG_CLASS_OR_STRING 7
1267-
#define ZPP_ERROR_WRONG_CLASS_OR_STRING_OR_NULL 8
1268-
#define ZPP_ERROR_UNEXPECTED_EXTRA_NAMED 9
1268+
#define ZPP_ERROR_WRONG_CLASS_OR_STRING 5
1269+
#define ZPP_ERROR_WRONG_CLASS_OR_STRING_OR_NULL 6
1270+
#define ZPP_ERROR_WRONG_CLASS_OR_LONG 7
1271+
#define ZPP_ERROR_WRONG_CLASS_OR_LONG_OR_NULL 8
1272+
#define ZPP_ERROR_WRONG_ARG 9
1273+
#define ZPP_ERROR_WRONG_COUNT 10
1274+
#define ZPP_ERROR_UNEXPECTED_EXTRA_NAMED 11
12691275

12701276
#define ZEND_PARSE_PARAMETERS_START_EX(flags, min_num_args, max_num_args) do { \
12711277
const int _flags = (flags); \
@@ -1675,6 +1681,21 @@ ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *
16751681

16761682
#define Z_PARAM_OBJ_OF_CLASS_OR_NULL(dest, _ce) \
16771683
Z_PARAM_OBJ_OF_CLASS_EX(dest, _ce, 1, 0)
1684+
1685+
#define Z_PARAM_OBJ_OF_CLASS_OR_LONG_EX(dest_obj, _ce, dest_long, is_null, allow_null) \
1686+
Z_PARAM_PROLOGUE(0, 0); \
1687+
if (UNEXPECTED(!zend_parse_arg_obj_or_long(_arg, &dest_obj, _ce, &dest_long, &is_null, allow_null))) { \
1688+
_error = ZSTR_VAL((_ce)->name); \
1689+
_error_code = allow_null ? ZPP_ERROR_WRONG_CLASS_OR_LONG_OR_NULL : ZPP_ERROR_WRONG_CLASS_OR_LONG; \
1690+
break; \
1691+
}
1692+
1693+
#define Z_PARAM_OBJ_OF_CLASS_OR_LONG(dest_obj, _ce, dest_long) \
1694+
Z_PARAM_OBJ_OF_CLASS_OR_LONG_EX(dest_obj, _ce, dest_long, _dummy, 0)
1695+
1696+
#define Z_PARAM_OBJ_OF_CLASS_OR_LONG_OR_NULL(dest_obj, _ce, dest_long, is_null) \
1697+
Z_PARAM_OBJ_OF_CLASS_OR_LONG_EX(dest_obj, _ce, dest_long, is_null, 1)
1698+
16781699
/* old "p" */
16791700
#define Z_PARAM_PATH_EX2(dest, dest_len, check_null, deref, separate) \
16801701
Z_PARAM_PROLOGUE(deref, separate); \
@@ -2028,6 +2049,29 @@ static zend_always_inline bool zend_parse_arg_array_ht(zval *arg, HashTable **de
20282049
return 1;
20292050
}
20302051

2052+
static zend_always_inline bool zend_parse_arg_array_ht_or_long(
2053+
zval *arg, HashTable **dest_ht, zend_long *dest_long, zend_bool *is_null, bool allow_null
2054+
) {
2055+
if (allow_null) {
2056+
*is_null = 0;
2057+
}
2058+
2059+
if (EXPECTED(Z_TYPE_P(arg) == IS_ARRAY)) {
2060+
*dest_ht = Z_ARRVAL_P(arg);
2061+
} else if (EXPECTED(Z_TYPE_P(arg) == IS_LONG)) {
2062+
*dest_ht = NULL;
2063+
*dest_long = Z_LVAL_P(arg);
2064+
} else if (allow_null && EXPECTED(Z_TYPE_P(arg) == IS_NULL)) {
2065+
*dest_ht = NULL;
2066+
*is_null = 1;
2067+
} else {
2068+
*dest_ht = NULL;
2069+
return zend_parse_arg_long_slow(arg, dest_long);
2070+
}
2071+
2072+
return 1;
2073+
}
2074+
20312075
static zend_always_inline bool zend_parse_arg_object(zval *arg, zval **dest, zend_class_entry *ce, bool check_null)
20322076
{
20332077
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,
20542098
return 1;
20552099
}
20562100

2101+
static zend_always_inline bool zend_parse_arg_obj_or_long(
2102+
zval *arg, zend_object **dest_obj, zend_class_entry *ce, zend_long *dest_long, zend_bool *is_null, bool allow_null
2103+
) {
2104+
if (allow_null) {
2105+
*is_null = 0;
2106+
}
2107+
2108+
if (EXPECTED(Z_TYPE_P(arg) == IS_OBJECT) && EXPECTED(instanceof_function(Z_OBJCE_P(arg), ce) != 0)) {
2109+
*dest_obj = Z_OBJ_P(arg);
2110+
} else if (EXPECTED(Z_TYPE_P(arg) == IS_LONG)) {
2111+
*dest_obj = NULL;
2112+
*dest_long = Z_LVAL_P(arg);
2113+
} else if (allow_null && EXPECTED(Z_TYPE_P(arg) == IS_NULL)) {
2114+
*dest_obj = NULL;
2115+
*is_null = 1;
2116+
} else {
2117+
*dest_obj = NULL;
2118+
return zend_parse_arg_long_slow(arg, dest_long);
2119+
}
2120+
2121+
return 1;
2122+
}
2123+
20572124
static zend_always_inline bool zend_parse_arg_resource(zval *arg, zval **dest, bool check_null)
20582125
{
20592126
if (EXPECTED(Z_TYPE_P(arg) == IS_RESOURCE)) {

0 commit comments

Comments
 (0)