Skip to content

Commit bb24c28

Browse files
committed
Fix in-place coercion for frameless calls
String parameters now create a temporary copy. Unfortunately, this requires some manual handling within the given frameless handlers.
1 parent 2702cc5 commit bb24c28

File tree

4 files changed

+159
-194
lines changed

4 files changed

+159
-194
lines changed

Zend/zend_builtin_functions.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1039,14 +1039,15 @@ ZEND_FUNCTION(class_exists)
10391039

10401040
ZEND_FRAMELESS_FUNCTION(class_exists, 1)
10411041
{
1042+
zval name_tmp;
10421043
zend_string *name;
10431044

1044-
if (!zend_parse_arg_str(arg1, &name, /* null_check */ false, 1)) {
1045-
zend_wrong_parameter_type_error(1, Z_EXPECTED_STRING, arg1);
1046-
RETURN_THROWS();
1047-
}
1045+
Z_FL_PARAM_STR(1, name, name_tmp);
10481046

10491047
_class_exists_impl(return_value, name, /* autoload */ true, ZEND_ACC_LINKED, ZEND_ACC_INTERFACE | ZEND_ACC_TRAIT);
1048+
1049+
fl_clean:
1050+
Z_FL_PARAM_FREE_STR(1, name_tmp);
10501051
}
10511052

10521053
/* {{{ Checks if the class exists */

Zend/zend_frameless_function.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,40 @@
2929
#define ZEND_FRAMELESS_FUNCTION(name, arity) \
3030
void ZEND_FRAMELESS_FUNCTION_NAME(name, arity)(DIRECT_FUNCTION_PARAMETERS_##arity)
3131

32+
#define Z_FL_PARAM_ZVAL(arg_num, dest) \
33+
dest = arg ## arg_num;
34+
#define Z_FL_PARAM_ARRAY(arg_num, dest) \
35+
if (!zend_parse_arg_array(arg ## arg_num, &dest, /* null_check */ false, /* or_object */ false)) { \
36+
zend_wrong_parameter_type_error(arg_num, Z_EXPECTED_ARRAY, arg ## arg_num); \
37+
goto fl_clean; \
38+
}
39+
#define Z_FL_PARAM_BOOL(arg_num, dest) \
40+
if (!zend_parse_arg_bool(arg ## arg_num, &dest, /* is_null */ NULL, /* null_check */ false, arg_num)) { \
41+
zend_wrong_parameter_type_error(arg_num, Z_EXPECTED_BOOL, arg ## arg_num); \
42+
goto fl_clean; \
43+
}
44+
#define Z_FL_PARAM_LONG(arg_num, dest) \
45+
if (!zend_parse_arg_long(arg ## arg_num, &dest, /* is_null */ NULL, /* null_check */ false, arg_num)) { \
46+
zend_wrong_parameter_type_error(arg_num, Z_EXPECTED_LONG, arg ## arg_num); \
47+
goto fl_clean; \
48+
}
49+
#define Z_FL_PARAM_STR(arg_num, dest, tmp) \
50+
if (Z_TYPE_P(arg ## arg_num) == IS_STRING) { \
51+
dest = Z_STR_P(arg ## arg_num); \
52+
} else { \
53+
ZVAL_COPY(&tmp, arg ## arg_num); \
54+
arg ## arg_num = &tmp; \
55+
if (!zend_parse_arg_str(arg ## arg_num, &dest, /* null_check */ false, arg_num)) { \
56+
zend_wrong_parameter_type_error(arg_num, Z_EXPECTED_STRING, arg ## arg_num); \
57+
goto fl_clean; \
58+
} \
59+
}
60+
#define Z_FL_PARAM_FREE_STR(arg_num, tmp) \
61+
if (UNEXPECTED(arg ## arg_num == &tmp)) { \
62+
zval_ptr_dtor(arg ## arg_num); \
63+
}
64+
#define Z_FL_FUNC_CLEAN() fm_func_end:
65+
3266
typedef struct _zval_struct zval;
3367

3468
typedef void (*zend_frameless_function_0)(zval *return_value);

ext/standard/array.c

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1684,31 +1684,28 @@ PHP_FUNCTION(in_array)
16841684

16851685
ZEND_FRAMELESS_FUNCTION(in_array, 2)
16861686
{
1687-
zval *array;
1687+
zval *value, *array;
16881688

1689-
if (!zend_parse_arg_array(arg2, &array, /* null_check */ false, /* or_object */ false)) {
1690-
zend_wrong_parameter_type_error(2, Z_EXPECTED_ARRAY, arg2);
1691-
RETURN_THROWS();
1692-
}
1689+
Z_FL_PARAM_ZVAL(1, value);
1690+
Z_FL_PARAM_ARRAY(2, array);
16931691

1694-
_php_search_array(return_value, arg1, array, false, 0);
1692+
_php_search_array(return_value, value, array, false, 0);
1693+
1694+
fl_clean:;
16951695
}
16961696

16971697
ZEND_FRAMELESS_FUNCTION(in_array, 3)
16981698
{
1699-
zval *array;
1700-
bool strict = 0;
1699+
zval *value, *array;
1700+
bool strict;
17011701

1702-
if (!zend_parse_arg_array(arg2, &array, /* null_check */ false, /* or_object */ false)) {
1703-
zend_wrong_parameter_type_error(2, Z_EXPECTED_ARRAY, arg2);
1704-
RETURN_THROWS();
1705-
}
1706-
if (!zend_parse_arg_bool(arg2, &strict, NULL, /* null_check */ false, 3)) {
1707-
zend_wrong_parameter_type_error(3, Z_EXPECTED_BOOL, arg3);
1708-
RETURN_THROWS();
1709-
}
1702+
Z_FL_PARAM_ZVAL(1, value);
1703+
Z_FL_PARAM_ARRAY(2, array);
1704+
Z_FL_PARAM_BOOL(3, strict);
1705+
1706+
_php_search_array(return_value, value, array, strict, 0);
17101707

1711-
_php_search_array(return_value, arg1, array, false, strict);
1708+
fl_clean:;
17121709
}
17131710

17141711
/* {{{ Searches the array for a given value and returns the corresponding key if successful */

0 commit comments

Comments
 (0)