summaryrefslogtreecommitdiffhomepage
path: root/src/class.c
diff options
context:
space:
mode:
authordearblue <[email protected]>2021-08-13 15:04:19 +0900
committerdearblue <[email protected]>2021-08-13 15:04:19 +0900
commit01da5e13920989b6c7ab97900659f570bdcb78f2 (patch)
tree5e0b9eea1c7ab20c8e018b54dce9f6f4af6ff36e /src/class.c
parent9e74aad43c8a7652c3cc0ffdc282c66ea866999b (diff)
downloadmruby-01da5e13920989b6c7ab97900659f570bdcb78f2.tar.gz
mruby-01da5e13920989b6c7ab97900659f570bdcb78f2.zip
Check the class with `I` specifier of `mrb_get_args()`
Previously, the `I` specifier only checked if the object was `MRB_TT_ISTRUCT`. So it was at risk of getting pointers to different C structs if multiple classes were to use the `MRB_TT_ISTRUCT` instance. Change this behavior and change the C argument corresponding to the `I` specifier to `(void *, struct RClass)`. This change is not compatible with the previous mruby. Please note that if the user uses the previous specifications, `SIGSEGV` may occur or the machine stack may be destroyed. resolve #5527
Diffstat (limited to 'src/class.c')
-rw-r--r--src/class.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/src/class.c b/src/class.c
index 6cf93414a..1b2beafe0 100644
--- a/src/class.c
+++ b/src/class.c
@@ -896,7 +896,7 @@ void mrb_hash_check_kdict(mrb_state *mrb, mrb_value self);
b: boolean [mrb_bool]
n: String/Symbol [mrb_sym]
d: data [void*,mrb_data_type const] 2nd argument will be used to check data type so it won't be modified; when ! follows, the value may be nil
- I: inline struct [void*]
+ I: inline struct [void*,struct RClass]
&: block [mrb_value] &! raises exception if no block given
*: rest argument [const mrb_value*,mrb_int] The rest of the arguments as an array; *! avoid copy of the stack
|: optional Following arguments are optional
@@ -1141,11 +1141,16 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
case 'I':
{
void* *p;
+ struct RClass *klass;
mrb_value ss;
p = va_arg(ap, void**);
+ klass = va_arg(ap, struct RClass*);
if (i < argc) {
ss = argv[i++];
+ if (!mrb_obj_is_kind_of(mrb, ss, klass)) {
+ mrb_raisef(mrb, E_TYPE_ERROR, "%v is not a %C", ss, klass);
+ }
if (!mrb_istruct_p(ss))
{
mrb_raisef(mrb, E_TYPE_ERROR, "%v is not inline struct", ss);