Prohibit Class#allocate in a different way

The method introduced by #5979 causes a fault by swapping classes.

```console
% bin/mruby -e 'Method = Proc; p Object.method(:inspect)'
zsh: segmentation fault (core dumped)  bin/mruby -e 'Method = Proc; p Object.method(:inspect)'
```

After applying this patch, a `TypeError` exception will be raised.

```console
% bin/mruby -e 'Method = Proc; p Object.method(:inspect)'
trace (most recent call last):
        [1] -e:1
-e:1:in method: allocation failure of Proc (TypeError)
```

However, if the `mrb_vtype` is the same object, the same care must still be taken as before.

```console
% bin/mruby -e 'Method = Binding; p method(:puts).eval("12345")'
trace (most recent call last):
        [1] -e:1
-e:1:in eval: wrong argument type nil (expected Proc) (TypeError)
```
This commit is contained in:
dearblue
2023-12-22 21:59:34 +09:00
parent fa75865a33
commit 8ecfacefca
11 changed files with 28 additions and 17 deletions
+3 -3
View File
@@ -1949,10 +1949,10 @@ mrb_instance_alloc(mrb_state *mrb, mrb_value cv)
else if (ttype == 0) {
ttype = MRB_TT_OBJECT;
}
if (MRB_UNDEF_ALLOCATOR_P(c)) {
mrb_raisef(mrb, E_TYPE_ERROR, "allocator undefined for %v", cv);
}
if (ttype <= MRB_TT_CPTR) {
if (ttype == MRB_TT_UNDEF) {
mrb_raisef(mrb, E_TYPE_ERROR, "allocator undefined for %v", cv);
}
mrb_raisef(mrb, E_TYPE_ERROR, "can't create instance of %v", cv);
}
o = (struct RObject*)mrb_obj_alloc(mrb, ttype, c);
-1
View File
@@ -476,7 +476,6 @@ mrb_obj_alloc(mrb_state *mrb, enum mrb_vtype ttype, struct RClass *cls)
}
tt = MRB_INSTANCE_TT(cls);
if (tt != MRB_TT_FALSE &&
tt != MRB_TT_UNDEF &&
ttype != MRB_TT_SCLASS &&
ttype != MRB_TT_ICLASS &&
ttype != MRB_TT_ENV &&
+4 -2
View File
@@ -2227,7 +2227,8 @@ mrb_init_numeric(mrb_state *mrb)
/* Integer Class */
mrb->integer_class = integer = mrb_define_class_id(mrb, MRB_SYM(Integer), numeric); /* 15.2.8 */
MRB_SET_INSTANCE_TT(integer, MRB_TT_UNDEF);
MRB_SET_INSTANCE_TT(integer, MRB_TT_INTEGER);
MRB_UNDEF_ALLOCATOR(integer);
mrb_undef_class_method_id(mrb, integer, MRB_SYM(new));
mrb_define_method_id(mrb, integer, MRB_OPSYM(pow), int_pow, MRB_ARGS_REQ(1));
mrb_define_method_id(mrb, integer, MRB_OPSYM(cmp), num_cmp, MRB_ARGS_REQ(1)); /* 15.2.8.3.1 */
@@ -2272,7 +2273,8 @@ mrb_init_numeric(mrb_state *mrb)
#ifndef MRB_NO_FLOAT
/* Float Class */
mrb->float_class = fl = mrb_define_class_id(mrb, MRB_SYM(Float), numeric); /* 15.2.9 */
MRB_SET_INSTANCE_TT(fl, MRB_TT_UNDEF);
MRB_SET_INSTANCE_TT(fl, MRB_TT_FLOAT);
MRB_UNDEF_ALLOCATOR(fl);
mrb_undef_class_method(mrb, fl, "new");
mrb_define_method_id(mrb, fl, MRB_OPSYM(pow), flo_pow, MRB_ARGS_REQ(1));
mrb_define_method_id(mrb, fl, MRB_OPSYM(div), flo_div, MRB_ARGS_REQ(1)); /* 15.2.9.3.6 */
+2 -3
View File
@@ -490,9 +490,8 @@ mrb_init_proc(mrb_state *mrb)
mrb_method_t m;
struct RClass *pc = mrb->proc_class = mrb_define_class_id(mrb, MRB_SYM(Proc), mrb->object_class); /* 15.2.17 */
MRB_SET_INSTANCE_TT(mrb->proc_class, MRB_TT_PROC);
MRB_SET_INSTANCE_TT(pc, MRB_TT_UNDEF);
MRB_SET_INSTANCE_TT(pc, MRB_TT_PROC);
MRB_UNDEF_ALLOCATOR(pc);
mrb_define_class_method_id(mrb, pc, MRB_SYM(new), mrb_proc_s_new, MRB_ARGS_NONE()|MRB_ARGS_BLOCK());
mrb_define_method_id(mrb, pc, MRB_SYM(initialize_copy), mrb_proc_init_copy, MRB_ARGS_REQ(1));
mrb_define_method_id(mrb, pc, MRB_SYM(arity), proc_arity, MRB_ARGS_NONE()); /* 15.2.17.4.2 */