Skip to content

Commit ea2d1e8

Browse files
committed
Fix strict arg parsing
1 parent 04504f7 commit ea2d1e8

File tree

5 files changed

+86
-20
lines changed

5 files changed

+86
-20
lines changed

Zend/zend_API.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,14 @@ ZEND_API bool ZEND_FASTCALL zend_parse_arg_bool_slow(const zval *arg, bool *dest
518518
}
519519
/* }}} */
520520

521+
ZEND_API bool ZEND_FASTCALL zend_flf_parse_arg_bool_slow(const zval *arg, bool *dest, uint32_t arg_num)
522+
{
523+
if (UNEXPECTED(ZEND_FLF_ARG_USES_STRICT_TYPES())) {
524+
return 0;
525+
}
526+
return zend_parse_arg_bool_weak(arg, dest, arg_num);
527+
}
528+
521529
ZEND_API bool ZEND_FASTCALL zend_parse_arg_long_weak(const zval *arg, zend_long *dest, uint32_t arg_num) /* {{{ */
522530
{
523531
if (EXPECTED(Z_TYPE_P(arg) == IS_DOUBLE)) {
@@ -597,6 +605,14 @@ ZEND_API bool ZEND_FASTCALL zend_parse_arg_long_slow(const zval *arg, zend_long
597605
}
598606
/* }}} */
599607

608+
ZEND_API bool ZEND_FASTCALL zend_flf_parse_arg_long_slow(const zval *arg, zend_long *dest, uint32_t arg_num)
609+
{
610+
if (UNEXPECTED(ZEND_FLF_ARG_USES_STRICT_TYPES())) {
611+
return 0;
612+
}
613+
return zend_parse_arg_long_weak(arg, dest, arg_num);
614+
}
615+
600616
ZEND_API bool ZEND_FASTCALL zend_parse_arg_double_weak(const zval *arg, double *dest, uint32_t arg_num) /* {{{ */
601617
{
602618
if (EXPECTED(Z_TYPE_P(arg) == IS_LONG)) {
@@ -738,6 +754,14 @@ ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_slow(zval *arg, zend_string **des
738754
}
739755
/* }}} */
740756

757+
ZEND_API bool ZEND_FASTCALL zend_flf_parse_arg_str_slow(zval *arg, zend_string **dest, uint32_t arg_num)
758+
{
759+
if (UNEXPECTED(ZEND_FLF_ARG_USES_STRICT_TYPES())) {
760+
return 0;
761+
}
762+
return zend_parse_arg_str_weak(arg, dest, arg_num);
763+
}
764+
741765
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) /* {{{ */
742766
{
743767
if (UNEXPECTED(ZEND_ARG_USES_STRICT_TYPES())) {

Zend/zend_API.h

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2175,7 +2175,11 @@ ZEND_API bool ZEND_FASTCALL zend_parse_arg_number_slow(zval *arg, zval **dest, u
21752175
ZEND_API bool ZEND_FASTCALL zend_parse_arg_number_or_str_slow(zval *arg, zval **dest, uint32_t arg_num);
21762176
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);
21772177

2178-
static zend_always_inline bool zend_parse_arg_bool(const zval *arg, bool *dest, bool *is_null, bool check_null, uint32_t arg_num)
2178+
ZEND_API bool ZEND_FASTCALL zend_flf_parse_arg_bool_slow(const zval *arg, bool *dest, uint32_t arg_num);
2179+
ZEND_API bool ZEND_FASTCALL zend_flf_parse_arg_str_slow(zval *arg, zend_string **dest, uint32_t arg_num);
2180+
ZEND_API bool ZEND_FASTCALL zend_flf_parse_arg_long_slow(const zval *arg, zend_long *dest, uint32_t arg_num);
2181+
2182+
static zend_always_inline bool zend_parse_arg_bool_ex(const zval *arg, bool *dest, bool *is_null, bool check_null, uint32_t arg_num, bool frameless)
21792183
{
21802184
if (check_null) {
21812185
*is_null = 0;
@@ -2188,12 +2192,21 @@ static zend_always_inline bool zend_parse_arg_bool(const zval *arg, bool *dest,
21882192
*is_null = 1;
21892193
*dest = 0;
21902194
} else {
2191-
return zend_parse_arg_bool_slow(arg, dest, arg_num);
2195+
if (frameless) {
2196+
return zend_flf_parse_arg_bool_slow(arg, dest, arg_num);
2197+
} else {
2198+
return zend_parse_arg_bool_slow(arg, dest, arg_num);
2199+
}
21922200
}
21932201
return 1;
21942202
}
21952203

2196-
static zend_always_inline bool zend_parse_arg_long(zval *arg, zend_long *dest, bool *is_null, bool check_null, uint32_t arg_num)
2204+
static zend_always_inline bool zend_parse_arg_bool(const zval *arg, bool *dest, bool *is_null, bool check_null, uint32_t arg_num)
2205+
{
2206+
return zend_parse_arg_bool_ex(arg, dest, is_null, check_null, arg_num, /* frameless */ false);
2207+
}
2208+
2209+
static zend_always_inline bool zend_parse_arg_long_ex(zval *arg, zend_long *dest, bool *is_null, bool check_null, uint32_t arg_num, bool frameless)
21972210
{
21982211
if (check_null) {
21992212
*is_null = 0;
@@ -2204,11 +2217,20 @@ static zend_always_inline bool zend_parse_arg_long(zval *arg, zend_long *dest, b
22042217
*is_null = 1;
22052218
*dest = 0;
22062219
} else {
2207-
return zend_parse_arg_long_slow(arg, dest, arg_num);
2220+
if (frameless) {
2221+
return zend_flf_parse_arg_long_slow(arg, dest, arg_num);
2222+
} else {
2223+
return zend_parse_arg_long_slow(arg, dest, arg_num);
2224+
}
22082225
}
22092226
return 1;
22102227
}
22112228

2229+
static zend_always_inline bool zend_parse_arg_long(zval *arg, zend_long *dest, bool *is_null, bool check_null, uint32_t arg_num)
2230+
{
2231+
return zend_parse_arg_long_ex(arg, dest, is_null, check_null, arg_num, /* frameless */ false);
2232+
}
2233+
22122234
static zend_always_inline bool zend_parse_arg_double(const zval *arg, double *dest, bool *is_null, bool check_null, uint32_t arg_num)
22132235
{
22142236
if (check_null) {
@@ -2249,18 +2271,27 @@ static zend_always_inline bool zend_parse_arg_number_or_str(zval *arg, zval **de
22492271
return true;
22502272
}
22512273

2252-
static zend_always_inline bool zend_parse_arg_str(zval *arg, zend_string **dest, bool check_null, uint32_t arg_num)
2274+
static zend_always_inline bool zend_parse_arg_str_ex(zval *arg, zend_string **dest, bool check_null, uint32_t arg_num, bool frameless)
22532275
{
22542276
if (EXPECTED(Z_TYPE_P(arg) == IS_STRING)) {
22552277
*dest = Z_STR_P(arg);
22562278
} else if (check_null && Z_TYPE_P(arg) == IS_NULL) {
22572279
*dest = NULL;
22582280
} else {
2259-
return zend_parse_arg_str_slow(arg, dest, arg_num);
2281+
if (frameless) {
2282+
return zend_flf_parse_arg_str_slow(arg, dest, arg_num);
2283+
} else {
2284+
return zend_parse_arg_str_slow(arg, dest, arg_num);
2285+
}
22602286
}
22612287
return 1;
22622288
}
22632289

2290+
static zend_always_inline bool zend_parse_arg_str(zval *arg, zend_string **dest, bool check_null, uint32_t arg_num)
2291+
{
2292+
return zend_parse_arg_str_ex(arg, dest, check_null, arg_num, /* frameless */ false);
2293+
}
2294+
22642295
static zend_always_inline bool zend_parse_arg_string(zval *arg, char **dest, size_t *dest_len, bool check_null, uint32_t arg_num)
22652296
{
22662297
zend_string *str;

Zend/zend_builtin_functions.c

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1830,17 +1830,23 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int
18301830
ZVAL_STRINGL(&tmp, ZSTR_VAL(name), ZSTR_LEN(name));
18311831
_zend_hash_append_ex(stack_frame, ZSTR_KNOWN(ZEND_STR_FUNCTION), &tmp, 1);
18321832
/* Steal file and line from the previous frame. */
1833-
if (prev_stack_frame) {
1834-
zval *file = zend_hash_find(prev_stack_frame, ZSTR_KNOWN(ZEND_STR_FILE));
1835-
if (file) {
1836-
Z_TRY_ADDREF_P(file);
1837-
_zend_hash_append_ex(stack_frame, ZSTR_KNOWN(ZEND_STR_FILE), file, 1);
1838-
zend_hash_del(prev_stack_frame, ZSTR_KNOWN(ZEND_STR_FILE));
1833+
if (call->func && ZEND_USER_CODE(call->func->common.type)) {
1834+
filename = call->func->op_array.filename;
1835+
if (call->opline->opcode == ZEND_HANDLE_EXCEPTION) {
1836+
if (EG(opline_before_exception)) {
1837+
lineno = EG(opline_before_exception)->lineno;
1838+
} else {
1839+
lineno = call->func->op_array.line_end;
1840+
}
1841+
} else {
1842+
lineno = call->opline->lineno;
18391843
}
1840-
zval *line = zend_hash_find(prev_stack_frame, ZSTR_KNOWN(ZEND_STR_LINE));
1841-
if (line) {
1842-
Z_TRY_ADDREF_P(file);
1843-
_zend_hash_append_ex(stack_frame, ZSTR_KNOWN(ZEND_STR_LINE), line, 1);
1844+
ZVAL_STR_COPY(&tmp, filename);
1845+
_zend_hash_append_ex(stack_frame, ZSTR_KNOWN(ZEND_STR_FILE), &tmp, 1);
1846+
ZVAL_LONG(&tmp, lineno);
1847+
_zend_hash_append_ex(stack_frame, ZSTR_KNOWN(ZEND_STR_LINE), &tmp, 1);
1848+
if (prev_stack_frame) {
1849+
zend_hash_del(prev_stack_frame, ZSTR_KNOWN(ZEND_STR_FILE));
18441850
zend_hash_del(prev_stack_frame, ZSTR_KNOWN(ZEND_STR_LINE));
18451851
}
18461852
}

Zend/zend_compile.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -649,6 +649,11 @@ ZEND_STATIC_ASSERT(ZEND_MM_ALIGNED_SIZE(sizeof(zval)) == sizeof(zval),
649649
EG(current_execute_data)->prev_execute_data->func && \
650650
ZEND_CALL_USES_STRICT_TYPES(EG(current_execute_data)->prev_execute_data))
651651

652+
#define ZEND_FLF_ARG_USES_STRICT_TYPES() \
653+
(EG(current_execute_data) && \
654+
EG(current_execute_data)->func && \
655+
ZEND_CALL_USES_STRICT_TYPES(EG(current_execute_data)))
656+
652657
#define ZEND_RET_USES_STRICT_TYPES() \
653658
ZEND_CALL_USES_STRICT_TYPES(EG(current_execute_data))
654659

Zend/zend_frameless_function.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,17 +41,17 @@
4141
goto flf_clean; \
4242
}
4343
#define Z_FLF_PARAM_BOOL(arg_num, dest) \
44-
if (!zend_parse_arg_bool(arg ## arg_num, &dest, /* is_null */ NULL, /* null_check */ false, arg_num)) { \
44+
if (!zend_parse_arg_bool_ex(arg ## arg_num, &dest, /* is_null */ NULL, /* null_check */ false, arg_num, /* frameless */ true)) { \
4545
zend_wrong_parameter_type_error(arg_num, Z_EXPECTED_BOOL, arg ## arg_num); \
4646
goto flf_clean; \
4747
}
4848
#define Z_FLF_PARAM_LONG(arg_num, dest) \
49-
if (!zend_parse_arg_long(arg ## arg_num, &dest, /* is_null */ NULL, /* null_check */ false, arg_num)) { \
49+
if (!zend_parse_arg_long_ex(arg ## arg_num, &dest, /* is_null */ NULL, /* null_check */ false, arg_num, /* frameless */ true)) { \
5050
zend_wrong_parameter_type_error(arg_num, Z_EXPECTED_LONG, arg ## arg_num); \
5151
goto flf_clean; \
5252
}
5353
#define Z_FLF_PARAM_LONG_OR_NULL(arg_num, is_null, dest) \
54-
if (!zend_parse_arg_long(arg ## arg_num, &dest, &is_null, /* null_check */ true, arg_num)) { \
54+
if (!zend_parse_arg_long_ex(arg ## arg_num, &dest, &is_null, /* null_check */ true, arg_num, /* frameless */ true)) { \
5555
zend_wrong_parameter_type_error(arg_num, Z_EXPECTED_LONG_OR_NULL, arg ## arg_num); \
5656
goto flf_clean; \
5757
}
@@ -61,7 +61,7 @@
6161
} else { \
6262
ZVAL_COPY(&tmp, arg ## arg_num); \
6363
arg ## arg_num = &tmp; \
64-
if (!zend_parse_arg_str(arg ## arg_num, &dest, /* null_check */ false, arg_num)) { \
64+
if (!zend_parse_arg_str_ex(arg ## arg_num, &dest, /* null_check */ false, arg_num, /* frameless */ true)) { \
6565
zend_wrong_parameter_type_error(arg_num, Z_EXPECTED_STRING, arg ## arg_num); \
6666
goto flf_clean; \
6767
} \

0 commit comments

Comments
 (0)