Skip to content

Commit 7978d13

Browse files
committed
ZPP: add F type check for callables that do not free trampolines
As refetching it with the new FCC API does get tedious
1 parent 5cc6979 commit 7978d13

File tree

2 files changed

+26
-15
lines changed

2 files changed

+26
-15
lines changed

Zend/zend_API.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -981,6 +981,7 @@ static const char *zend_parse_arg_impl(zval *arg, va_list *va, const char **spec
981981
}
982982
break;
983983

984+
case 'F':
984985
case 'f':
985986
{
986987
zend_fcall_info *fci = va_arg(*va, zend_fcall_info *);
@@ -995,10 +996,12 @@ static const char *zend_parse_arg_impl(zval *arg, va_list *va, const char **spec
995996

996997
if (zend_fcall_info_init(arg, 0, fci, fcc, NULL, &is_callable_error) == SUCCESS) {
997998
ZEND_ASSERT(!is_callable_error);
998-
/* Release call trampolines: The function may not get called, in which case
999-
* the trampoline will leak. Force it to be refetched during
1000-
* zend_call_function instead. */
1001-
zend_release_fcall_info_cache(fcc);
999+
if (c == 'f') {
1000+
/* Release call trampolines: The function may not get called, in which case
1001+
* the trampoline will leak. Force it to be refetched during
1002+
* zend_call_function instead. */
1003+
zend_release_fcall_info_cache(fcc);
1004+
}
10021005
break;
10031006
}
10041007

@@ -1109,7 +1112,7 @@ static zend_result zend_parse_va_args(uint32_t num_args, const char *type_spec,
11091112
case 'o': case 'O':
11101113
case 'z': case 'Z':
11111114
case 'C': case 'h':
1112-
case 'f': case 'A':
1115+
case 'f': case 'F': case 'A':
11131116
case 'H': case 'p':
11141117
case 'S': case 'P':
11151118
case 'L': case 'n':

Zend/zend_API.h

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1794,9 +1794,9 @@ ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *
17941794
Z_PARAM_DOUBLE_EX(dest, is_null, 1, 0)
17951795

17961796
/* old "f" */
1797-
#define Z_PARAM_FUNC_EX(dest_fci, dest_fcc, check_null, deref) \
1797+
#define Z_PARAM_FUNC_EX(dest_fci, dest_fcc, check_null, deref, free_trampoline) \
17981798
Z_PARAM_PROLOGUE(deref, 0); \
1799-
if (UNEXPECTED(!zend_parse_arg_func(_arg, &dest_fci, &dest_fcc, check_null, &_error))) { \
1799+
if (UNEXPECTED(!zend_parse_arg_func(_arg, &dest_fci, &dest_fcc, check_null, &_error, free_trampoline))) { \
18001800
if (!_error) { \
18011801
_expected_type = check_null ? Z_EXPECTED_FUNC_OR_NULL : Z_EXPECTED_FUNC; \
18021802
_error_code = ZPP_ERROR_WRONG_ARG; \
@@ -1807,13 +1807,19 @@ ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *
18071807
} \
18081808

18091809
#define Z_PARAM_FUNC(dest_fci, dest_fcc) \
1810-
Z_PARAM_FUNC_EX(dest_fci, dest_fcc, 0, 0)
1810+
Z_PARAM_FUNC_EX(dest_fci, dest_fcc, 0, 0, true)
1811+
1812+
#define Z_PARAM_FUNC_NO_TRAMPOLINE_FREE(dest_fci, dest_fcc) \
1813+
Z_PARAM_FUNC_EX(dest_fci, dest_fcc, 0, 0, false)
18111814

18121815
#define Z_PARAM_FUNC_OR_NULL(dest_fci, dest_fcc) \
1813-
Z_PARAM_FUNC_EX(dest_fci, dest_fcc, 1, 0)
1816+
Z_PARAM_FUNC_EX(dest_fci, dest_fcc, 1, 0, true)
1817+
1818+
#define Z_PARAM_FUNC_NO_TRAMPOLINE_FREE_OR_NULL(dest_fci, dest_fcc) \
1819+
Z_PARAM_FUNC_EX(dest_fci, dest_fcc, 1, 0, false)
18141820

18151821
#define Z_PARAM_FUNC_OR_NULL_WITH_ZVAL(dest_fci, dest_fcc, dest_zp) \
1816-
Z_PARAM_FUNC_EX(dest_fci, dest_fcc, 1, 0) \
1822+
Z_PARAM_FUNC_EX(dest_fci, dest_fcc, 1, 0, true) \
18171823
Z_PARAM_GET_PREV_ZVAL(dest_zp)
18181824

18191825
/* old "h" */
@@ -2428,7 +2434,7 @@ static zend_always_inline bool zend_parse_arg_resource(zval *arg, zval **dest, b
24282434
return 1;
24292435
}
24302436

2431-
static zend_always_inline bool zend_parse_arg_func(zval *arg, zend_fcall_info *dest_fci, zend_fcall_info_cache *dest_fcc, bool check_null, char **error)
2437+
static zend_always_inline bool zend_parse_arg_func(zval *arg, zend_fcall_info *dest_fci, zend_fcall_info_cache *dest_fcc, bool check_null, char **error, bool free_trampoline)
24322438
{
24332439
if (check_null && UNEXPECTED(Z_TYPE_P(arg) == IS_NULL)) {
24342440
dest_fci->size = 0;
@@ -2437,10 +2443,12 @@ static zend_always_inline bool zend_parse_arg_func(zval *arg, zend_fcall_info *d
24372443
} else if (UNEXPECTED(zend_fcall_info_init(arg, 0, dest_fci, dest_fcc, NULL, error) != SUCCESS)) {
24382444
return 0;
24392445
}
2440-
/* Release call trampolines: The function may not get called, in which case
2441-
* the trampoline will leak. Force it to be refetched during
2442-
* zend_call_function instead. */
2443-
zend_release_fcall_info_cache(dest_fcc);
2446+
if (free_trampoline) {
2447+
/* Release call trampolines: The function may not get called, in which case
2448+
* the trampoline will leak. Force it to be refetched during
2449+
* zend_call_function instead. */
2450+
zend_release_fcall_info_cache(dest_fcc);
2451+
}
24442452
return 1;
24452453
}
24462454

0 commit comments

Comments
 (0)