mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
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.
This commit is contained in:
+5
-3
@@ -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, "")));
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user