From bec074e6a31fd7a577e2c0e726167da8dc44c4c6 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Fri, 8 Oct 2021 15:31:37 +0900 Subject: [PATCH] vm.c: check call stack depth before pushing the frame. Existing call stack depth checks are unified into this check in `cipush()`. The maximum depth is now specified by `MRB_CALL_LEVEL_MAX` (the default is 512). The older `MRB_FUNCALL_DEPTH_MAX` is no longer used. --- src/vm.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/vm.c b/src/vm.c index f3332353b6..69a8732813 100644 --- a/src/vm.c +++ b/src/vm.c @@ -39,9 +39,9 @@ void abort(void); #define MRB_STACK_GROWTH 128 #endif -/* Maximum mrb_funcall() depth. Should be set lower on memory constrained systems. */ -#ifndef MRB_FUNCALL_DEPTH_MAX -#define MRB_FUNCALL_DEPTH_MAX 512 +/* Maximum recursive depth. Should be set lower on memory constrained systems. */ +#ifndef MRB_CALL_LEVEL_MAX +#define MRB_CALL_LEVEL_MAX 512 #endif /* Maximum stack depth. Should be set lower on memory constrained systems. @@ -251,6 +251,9 @@ cipush(mrb_state *mrb, mrb_int push_stacks, uint8_t cci, if (ci + 1 == c->ciend) { ptrdiff_t size = ci - c->cibase; + if (size > MRB_CALL_LEVEL_MAX) { + mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err)); + } c->cibase = (mrb_callinfo *)mrb_realloc(mrb, c->cibase, sizeof(mrb_callinfo)*size*2); c->ci = c->cibase + size; c->ciend = c->cibase + size * 2; @@ -464,9 +467,6 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc mrb->c->ci->stack[n+1] = args; argc = -1; } - if (mrb->c->ci - mrb->c->cibase > MRB_FUNCALL_DEPTH_MAX) { - mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err)); - } ci = cipush(mrb, n, 0, c, NULL, mid, argc); if (argc < 0) argc = 1; if (mrb->c->stbase <= argv && argv < mrb->c->stend) { @@ -740,9 +740,6 @@ mrb_yield_with_class(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value } ci = mrb->c->ci; n = ci_nregs(ci); - if (ci - mrb->c->cibase > MRB_FUNCALL_DEPTH_MAX) { - mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err)); - } p = mrb_proc_ptr(b); ci = cipush(mrb, n, CINFO_SKIP, c, p, mid, 0 /* dummy */); if (argc >= CALL_MAXARGS) {