From 6c06b4cd9d942e41269bf8b266bc20f0abbfdaa4 Mon Sep 17 00:00:00 2001 From: dearblue Date: Mon, 13 Apr 2026 21:41:34 +0900 Subject: [PATCH] Early conversion of `mesg` to a string object in `mrb_sys_fail()` `mrb_class_get_id()` may call the `#const_missing` method. Therefore, if the `mesg` string originates from a string object, it may reference an invalid address. And since `errno` might also change during the call to `#const_missing`, save this as well beforehand. Also, while `mrb_class_defined_id()` does not currently call the `#const_defined?` method, it is unclear whether this will remain the case in the future. --- src/error.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/error.c b/src/error.c index cce382537..b76f17369 100644 --- a/src/error.c +++ b/src/error.c @@ -592,18 +592,20 @@ mrb_make_exception(mrb_state *mrb, mrb_value exc, mrb_value mesg) MRB_API mrb_noreturn void mrb_sys_fail(mrb_state *mrb, const char *mesg) { + mrb_int no = (mrb_int)errno; + mrb_value mesg_str = mesg ? mrb_str_new_cstr(mrb, mesg) : mrb_nil_value(); + if (mrb_class_defined_id(mrb, MRB_SYM(SystemCallError))) { struct RClass *sce = mrb_class_get_id(mrb, MRB_SYM(SystemCallError)); - mrb_int no = (mrb_int)errno; if (mesg != NULL) { - mrb_funcall_id(mrb, mrb_obj_value(sce), MRB_SYM(_sys_fail), 2, mrb_fixnum_value(no), mrb_str_new_cstr(mrb, mesg)); + mrb_funcall_id(mrb, mrb_obj_value(sce), MRB_SYM(_sys_fail), 2, mrb_fixnum_value(no), mesg_str); } else { mrb_funcall_id(mrb, mrb_obj_value(sce), MRB_SYM(_sys_fail), 1, mrb_fixnum_value(no)); } } - mrb_raise(mrb, E_RUNTIME_ERROR, mesg); + mrb_exc_raise(mrb, mrb_exc_new_str(mrb, E_RUNTIME_ERROR, mesg ? mesg_str : mrb_str_new_lit(mrb, ""))); } /*