From f58f7f25a38a452ac7b288dab2e463e2d3076db5 Mon Sep 17 00:00:00 2001 From: Satoshi Tagomori Date: Sat, 20 Sep 2025 14:17:14 +0900 Subject: [PATCH] Fix bug of uninitialized variable, missed EoCFP, return values --- vm.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/vm.c b/vm.c index 6d63a5eeaf..1867f95fd9 100644 --- a/vm.c +++ b/vm.c @@ -99,18 +99,37 @@ static const VALUE * VM_EP_RUBY_LEP(const rb_execution_context_t *ec, const rb_control_frame_t *current_cfp) { const VALUE *ep = current_cfp->ep; - const rb_control_frame_t *cfp, *checkpoint_cfp = current_cfp; + const rb_control_frame_t * const eocfp = RUBY_VM_END_CONTROL_FRAME(ec); /* end of control frame pointer */ + const rb_control_frame_t *cfp = NULL, *checkpoint_cfp = current_cfp; while (!VM_ENV_LOCAL_P(ep) || VM_ENV_FRAME_TYPE_P(ep, VM_FRAME_MAGIC_CFUNC)) { while (!VM_ENV_LOCAL_P(ep)) { ep = VM_ENV_PREV_EP(ep); } - while (VM_ENV_FRAME_TYPE_P(ep, VM_FRAME_MAGIC_CFUNC)) { + while (VM_ENV_FLAGS(ep, VM_FRAME_FLAG_CFRAME) != 0) { if (!cfp) { cfp = rb_vm_search_cf_from_ep(ec, checkpoint_cfp, ep); + VM_ASSERT(cfp, "rb_vm_search_cf_from_ep should return a valid cfp for the ep"); + VM_ASSERT(cfp->ep == ep); + } + if (!cfp) { + return NULL; + } + VM_ASSERT(cfp->ep); + VM_ASSERT(cfp->ep == ep); + + if (VM_FRAME_FINISHED_P(cfp)) { + rb_bug("CFUNC frame should not FINISHED"); } cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp); + if (cfp >= eocfp) { + return NULL; + } + VM_ASSERT(cfp, "CFUNC should have a valid previous control frame"); ep = cfp->ep; + if (!ep) { + return NULL; + } } checkpoint_cfp = cfp; cfp = NULL;