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
+4 -2
View File
@@ -546,7 +546,8 @@ mrb_mruby_method_gem_init(mrb_state* mrb)
struct RClass *unbound_method = mrb_define_class_id(mrb, MRB_SYM(UnboundMethod), mrb->object_class);
struct RClass *method = mrb_define_class_id(mrb, MRB_SYM(Method), mrb->object_class);
MRB_SET_INSTANCE_TT(unbound_method, MRB_TT_UNDEF);
MRB_SET_INSTANCE_TT(unbound_method, MRB_TT_OBJECT);
MRB_UNDEF_ALLOCATOR(unbound_method);
mrb_undef_class_method(mrb, unbound_method, "new");
mrb_define_method(mrb, unbound_method, "bind", unbound_method_bind, MRB_ARGS_REQ(1));
mrb_define_method(mrb, unbound_method, "super_method", method_super_method, MRB_ARGS_NONE());
@@ -561,7 +562,8 @@ mrb_mruby_method_gem_init(mrb_state* mrb)
mrb_define_method(mrb, unbound_method, "owner", method_owner, MRB_ARGS_NONE());
mrb_define_method(mrb, unbound_method, "name", method_name, MRB_ARGS_NONE());
MRB_SET_INSTANCE_TT(method, MRB_TT_UNDEF);
MRB_SET_INSTANCE_TT(method, MRB_TT_OBJECT);
MRB_UNDEF_ALLOCATOR(method);
mrb_undef_class_method(mrb, method, "new");
mrb_define_method(mrb, method, "==", method_eql, MRB_ARGS_REQ(1));
mrb_define_method(mrb, method, "eql?", method_eql, MRB_ARGS_REQ(1));