summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNobuyoshi Nakada <nobu@ruby-lang.org>2021-11-08 01:43:06 +0900
committerNobuyoshi Nakada <nobu@ruby-lang.org>2021-11-08 15:14:34 +0900
commit833c69ee829dc9d9c2ce0f89c7f5e88200b94a0f (patch)
tree3436fdf74c7fb195b39dd392e193bef31e0f57b0
parentf3bae1a2063766c29bc6f8db76abfa619ba462f7 (diff)
downloadruby-833c69ee829dc9d9c2ce0f89c7f5e88200b94a0f.tar.gz
Convert IDs to Integers
As the ID serial is 32bit value and internal IDs created in the parser are assigned from its maximum value, Symbol converted from it will exceed 32bit and overflow on 32bit platforms.
-rw-r--r--vm.c35
1 files changed, 31 insertions, 4 deletions
diff --git a/vm.c b/vm.c
index 307e9ab931..f13e07cef3 100644
--- a/vm.c
+++ b/vm.c
@@ -994,6 +994,24 @@ struct collect_outer_variable_name_data {
bool isolate;
};
+static VALUE
+ID2NUM(ID id)
+{
+ if (SIZEOF_VOIDP > SIZEOF_LONG)
+ return ULL2NUM(id);
+ else
+ return ULONG2NUM(id);
+}
+
+static ID
+NUM2ID(VALUE num)
+{
+ if (SIZEOF_VOIDP > SIZEOF_LONG)
+ return (ID)NUM2ULL(num);
+ else
+ return (ID)NUM2ULONG(num);
+}
+
static enum rb_id_table_iterator_result
collect_outer_variable_names(ID id, VALUE val, void *ptr)
{
@@ -1012,7 +1030,7 @@ collect_outer_variable_names(ID id, VALUE val, void *ptr)
store = &data->read_only;
}
if (*store == Qfalse) *store = rb_ary_new();
- rb_ary_push(*store, ID2SYM(id));
+ rb_ary_push(*store, ID2NUM(id));
}
return ID_TABLE_CONTINUE;
}
@@ -1029,7 +1047,7 @@ env_copy(const VALUE *src_ep, VALUE read_only_variables)
if (read_only_variables) {
for (int i=RARRAY_LENINT(read_only_variables)-1; i>=0; i--) {
- ID id = SYM2ID(RARRAY_AREF(read_only_variables, i));
+ ID id = NUM2ID(RARRAY_AREF(read_only_variables, i));
for (unsigned int j=0; j<src_env->iseq->body->local_table_size; j++) {
if (id == src_env->iseq->body->local_table[j]) {
@@ -1091,8 +1109,17 @@ proc_shared_outer_variables(struct rb_id_table *outer_variables, bool isolate, c
rb_id_table_foreach(outer_variables, collect_outer_variable_names, (void *)&data);
if (data.ary != Qfalse) {
- VALUE str = rb_sprintf("can not %s because it accesses outer variables (%"PRIsVALUE")", message,
- rb_ary_join(data.ary, rb_str_new2(", ")));
+ VALUE str = rb_sprintf("can not %s because it accesses outer variables", message);
+ VALUE ary = data.ary;
+ const char *sep = " (";
+ for (long i = 0; i < RARRAY_LEN(ary); i++) {
+ VALUE name = rb_id2str(NUM2ID(RARRAY_AREF(ary, i)));
+ if (!name) continue;
+ rb_str_cat_cstr(str, sep);
+ sep = ", ";
+ rb_str_append(str, name);
+ }
+ if (*sep == ',') rb_str_cat_cstr(str, ")");
rb_str_cat_cstr(str, data.yield ? " and uses `yield'." : ".");
rb_exc_raise(rb_exc_new_str(rb_eArgError, str));
}