Skip to content

Commit 4a078ec

Browse files
committed
We need to release the trampoline before the closure
As the trampoline will refer to a zend_function* defined on the closure CE
1 parent 85adfd5 commit 4a078ec

File tree

1 file changed

+6
-4
lines changed

1 file changed

+6
-4
lines changed

Zend/zend_API.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -743,15 +743,15 @@ static zend_always_inline bool zend_fcc_equals(const zend_fcall_info_cache* a, c
743743
static zend_always_inline void zend_fcc_addref(zend_fcall_info_cache *fcc)
744744
{
745745
ZEND_ASSERT(ZEND_FCC_INITIALIZED(*fcc) && "FCC Not initialized, possibly refetch trampoline freed by ZPP?");
746-
/*
746+
/* If the cached trampoline is set, free it */
747747
if (UNEXPECTED(fcc->function_handler == &EG(trampoline))) {
748-
zend_function *copy = emalloc(sizeof(zend_function));
748+
zend_function *copy = (zend_function*)emalloc(sizeof(zend_function));
749749

750750
memcpy(copy, fcc->function_handler, sizeof(zend_function));
751751
fcc->function_handler->common.function_name = NULL;
752752
fcc->function_handler = copy;
753+
memset(&EG(trampoline), 0, sizeof(zend_function));
753754
}
754-
*/
755755
if (fcc->object) {
756756
GC_ADDREF(fcc->object);
757757
}
@@ -768,13 +768,15 @@ static zend_always_inline void zend_fcc_dup(/* restrict */ zend_fcall_info_cache
768768

769769
static zend_always_inline void zend_fcc_dtor(zend_fcall_info_cache *fcc)
770770
{
771+
ZEND_ASSERT(fcc->function_handler);
771772
if (fcc->object) {
772773
OBJ_RELEASE(fcc->object);
773774
}
775+
/* Need to free potential trampoline (__call/__callStatic) copied function handler before releasing the closure */
776+
zend_release_fcall_info_cache(fcc);
774777
if (fcc->closure) {
775778
OBJ_RELEASE(fcc->closure);
776779
}
777-
zend_release_fcall_info_cache(fcc);
778780
memcpy(fcc, &empty_fcall_info_cache, sizeof(zend_fcall_info_cache));
779781
}
780782

0 commit comments

Comments
 (0)