Skip to content

Commit 4f6fbd9

Browse files
committed
Do not use zend_fcall_info_argp() for ticks and shutdown functions
Instead handle the copying and safe reallocation of the param zvals ourself.
1 parent 6b54811 commit 4f6fbd9

File tree

1 file changed

+24
-19
lines changed

1 file changed

+24
-19
lines changed

ext/standard/basic_functions.c

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1594,36 +1594,45 @@ PHP_FUNCTION(forward_static_call_array)
15941594
}
15951595
/* }}} */
15961596

1597-
static void fci_addref(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache)
1597+
static void php_user_callable_addref_with_params(zend_fcall_info *fci, zend_fcall_info_cache *fcc, const zval *params)
15981598
{
15991599
Z_TRY_ADDREF(fci->function_name);
1600-
if (fci_cache->object) {
1601-
GC_ADDREF(fci_cache->object);
1600+
fci->params = NULL;
1601+
if (params) {
1602+
ZEND_ASSERT(fci->param_count > 0);
1603+
fci->params = (zval *) safe_erealloc(fci->params, sizeof(zval), fci->param_count, 0);
1604+
for (uint32_t i = 0; i < fci->param_count; ++i) {
1605+
ZVAL_COPY(&fci->params[i], &params[i]);
1606+
}
16021607
}
1608+
zend_fcc_addref(fcc);
16031609
}
16041610

1605-
static void fci_release(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache)
1611+
static void php_user_callable_dtor_with_params(zend_fcall_info *fci, zend_fcall_info_cache *fcc)
16061612
{
16071613
zval_ptr_dtor(&fci->function_name);
1608-
if (fci_cache->object) {
1609-
zend_object_release(fci_cache->object);
1614+
if (fci->params) {
1615+
ZEND_ASSERT(fci->param_count > 0);
1616+
for (uint32_t i = 0; i < fci->param_count; ++i) {
1617+
zval_ptr_dtor(&fci->params[i]);
1618+
}
1619+
efree(fci->params);
16101620
}
1621+
zend_fcc_dtor(fcc);
16111622
}
16121623

16131624
void user_shutdown_function_dtor(zval *zv) /* {{{ */
16141625
{
16151626
php_shutdown_function_entry *shutdown_function_entry = Z_PTR_P(zv);
16161627

1617-
zend_fcall_info_args_clear(&shutdown_function_entry->fci, true);
1618-
fci_release(&shutdown_function_entry->fci, &shutdown_function_entry->fci_cache);
1628+
php_user_callable_dtor_with_params(&shutdown_function_entry->fci, &shutdown_function_entry->fci_cache);
16191629
efree(shutdown_function_entry);
16201630
}
16211631
/* }}} */
16221632

16231633
void user_tick_function_dtor(user_tick_function_entry *tick_function_entry) /* {{{ */
16241634
{
1625-
zend_fcall_info_args_clear(&tick_function_entry->fci, true);
1626-
fci_release(&tick_function_entry->fci, &tick_function_entry->fci_cache);
1635+
php_user_callable_dtor_with_params(&tick_function_entry->fci, &tick_function_entry->fci_cache);
16271636
}
16281637
/* }}} */
16291638

@@ -1721,16 +1730,14 @@ PHPAPI void php_free_shutdown_functions(void) /* {{{ */
17211730
PHP_FUNCTION(register_shutdown_function)
17221731
{
17231732
php_shutdown_function_entry entry;
1724-
zval *params = NULL;
1725-
uint32_t param_count = 0;
17261733
bool status;
1734+
zval *params = NULL;
17271735

1728-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "f*", &entry.fci, &entry.fci_cache, &params, &param_count) == FAILURE) {
1736+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "f*", &entry.fci, &entry.fci_cache, &params, &entry.fci.param_count) == FAILURE) {
17291737
RETURN_THROWS();
17301738
}
17311739

1732-
fci_addref(&entry.fci, &entry.fci_cache);
1733-
zend_fcall_info_argp(&entry.fci, param_count, params);
1740+
php_user_callable_addref_with_params(&entry.fci, &entry.fci_cache, params);
17341741

17351742
status = append_user_shutdown_function(&entry);
17361743
ZEND_ASSERT(status);
@@ -2310,15 +2317,13 @@ PHP_FUNCTION(register_tick_function)
23102317
{
23112318
user_tick_function_entry tick_fe;
23122319
zval *params = NULL;
2313-
uint32_t param_count = 0;
23142320

2315-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "f*", &tick_fe.fci, &tick_fe.fci_cache, &params, &param_count) == FAILURE) {
2321+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "f*", &tick_fe.fci, &tick_fe.fci_cache, &params, &tick_fe.fci.param_count) == FAILURE) {
23162322
RETURN_THROWS();
23172323
}
23182324

23192325
tick_fe.calling = false;
2320-
fci_addref(&tick_fe.fci, &tick_fe.fci_cache);
2321-
zend_fcall_info_argp(&tick_fe.fci, param_count, params);
2326+
php_user_callable_addref_with_params(&tick_fe.fci, &tick_fe.fci_cache, params);
23222327

23232328
if (!BG(user_tick_functions)) {
23242329
BG(user_tick_functions) = (zend_llist *) emalloc(sizeof(zend_llist));

0 commit comments

Comments
 (0)