ruby-changes:69638
From: Nobuyoshi <ko1@a...>
Date: Mon, 8 Nov 2021 15:15:08 +0900 (JST)
Subject: [ruby-changes:69638] 833c69ee82 (master): Convert IDs to Integers
https://git.ruby-lang.org/ruby.git/commit/?id=833c69ee82 From 833c69ee829dc9d9c2ce0f89c7f5e88200b94a0f Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada <nobu@r...> Date: Mon, 8 Nov 2021 01:43:06 +0900 Subject: 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. --- vm.c | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/vm.c b/vm.c index 307e9ab931c..f13e07cef3d 100644 --- a/vm.c +++ b/vm.c @@ -994,6 +994,24 @@ struct collect_outer_variable_name_data { https://github.com/ruby/ruby/blob/trunk/vm.c#L994 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) https://github.com/ruby/ruby/blob/trunk/vm.c#L1030 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) https://github.com/ruby/ruby/blob/trunk/vm.c#L1047 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 https://github.com/ruby/ruby/blob/trunk/vm.c#L1109 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)); } -- cgit v1.2.1 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/