summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNobuyoshi Nakada <nobu@ruby-lang.org>2021-09-23 00:04:37 +0900
committerNobuyoshi Nakada <nobu@ruby-lang.org>2021-09-23 14:01:08 +0900
commit7cec727612c7b3a3c05b6d9efa16a6d4557d2f47 (patch)
tree85d58ef137de4c89ae4d07be4a2d11a67edddb00
parent64bdad59918f8d439ffef9000ea4e670a8bdd0f5 (diff)
Check instance variable count overflow
-rw-r--r--marshal.c14
1 files changed, 7 insertions, 7 deletions
diff --git a/marshal.c b/marshal.c
index 036bde3ae4..744267afaf 100644
--- a/marshal.c
+++ b/marshal.c
@@ -632,7 +632,9 @@ static int
obj_count_ivars(st_data_t key, st_data_t val, st_data_t a)
{
ID id = (ID)key;
- if (!to_be_skipped_id(id)) ++*(st_index_t *)a;
+ if (!to_be_skipped_id(id) && UNLIKELY(!++*(st_index_t *)a)) {
+ rb_raise(rb_eRuntimeError, "too many instance variables");
+ }
return ST_CONTINUE;
}
@@ -691,9 +693,7 @@ w_encoding(VALUE encname, struct dump_call_arg *arg)
static st_index_t
has_ivars(VALUE obj, VALUE encname, VALUE *ivobj)
{
- st_index_t enc = !NIL_P(encname);
- st_index_t num = 0;
- st_index_t ruby2_keywords_flag = 0;
+ st_index_t num = !NIL_P(encname);
if (SPECIAL_CONST_P(obj)) goto generic;
switch (BUILTIN_TYPE(obj)) {
@@ -702,15 +702,15 @@ has_ivars(VALUE obj, VALUE encname, VALUE *ivobj)
case T_MODULE:
break; /* counted elsewhere */
case T_HASH:
- ruby2_keywords_flag = rb_hash_ruby2_keywords_p(obj) ? 1 : 0;
+ if (rb_hash_ruby2_keywords_p(obj)) ++num;
/* fall through */
default:
generic:
rb_ivar_foreach(obj, obj_count_ivars, (st_data_t)&num);
- if (ruby2_keywords_flag || num) *ivobj = obj;
+ if (num) *ivobj = obj;
}
- return num + enc + ruby2_keywords_flag;
+ return num;
}
static void