From 6fad067ded007b3ee9c4bb899f8e4dad7238300b Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Fri, 15 Dec 2023 18:17:43 +0900 Subject: [PATCH] mruby-binding: raise in upper count check We count `Proc` upper links then check for upper bounds (default:20), but now we raise an exception as soon as the count exceeds the limit so that we can avoid traverse unnecessary upper links. --- mrbgems/mruby-binding/src/binding.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/mrbgems/mruby-binding/src/binding.c b/mrbgems/mruby-binding/src/binding.c index 7a0a577fe..08e81fb72 100644 --- a/mrbgems/mruby-binding/src/binding.c +++ b/mrbgems/mruby-binding/src/binding.c @@ -106,15 +106,17 @@ binding_env_new_lvspace(mrb_state *mrb, const struct REnv *e) return env; } -static size_t -binding_proc_upper_count(const struct RProc *proc) +static void +binding_check_proc_upper_count(mrb_state *mrb, const struct RProc *proc) { - size_t count = 0; - for (; proc && !MRB_PROC_CFUNC_P(proc); proc = proc->upper) { + for (size_t count = 0; proc && !MRB_PROC_CFUNC_P(proc); proc = proc->upper) { count++; + if (count > BINDING_UPPER_MAX) { + mrb_raise(mrb, E_RUNTIME_ERROR, + "too many upper procs for local variables (mruby limitation; maximum is " MRB_STRINGIZE(BINDING_UPPER_MAX) ")"); + } if (MRB_PROC_SCOPE_P(proc)) break; } - return count; } mrb_bool @@ -166,10 +168,7 @@ binding_initialize_copy(mrb_state *mrb, mrb_value binding) lvspace = binding_wrap_lvspace(mrb, src_proc->upper, &env); } else { - if (binding_proc_upper_count(src_proc) > BINDING_UPPER_MAX) { - mrb_raise(mrb, E_RUNTIME_ERROR, - "too many upper procs for local variables (mruby limitation; maximum is " MRB_STRINGIZE(BINDING_UPPER_MAX) ")"); - } + binding_check_proc_upper_count(mrb, src_proc); env = src_env; lvspace = binding_wrap_lvspace(mrb, src_proc, &env);