diff --git a/marshal.c b/marshal.c index 7152be2924a0aa..25b693d8da25b7 100644 --- a/marshal.c +++ b/marshal.c @@ -1803,6 +1803,20 @@ r_object0(struct load_arg *arg, bool partial, int *ivp, VALUE extmod) return r_object_for(arg, partial, ivp, extmod, type); } +static int +r_move_ivar(st_data_t k, st_data_t v, st_data_t d) +{ + ID key = (ID)k; + VALUE value = (VALUE)v; + VALUE dest = (VALUE)d; + + if (rb_is_instance_id(key)) { + rb_ivar_set(dest, key, value); + return ST_DELETE; + } + return ST_CONTINUE; +} + static VALUE r_object_for(struct load_arg *arg, bool partial, int *ivp, VALUE extmod, int type) { @@ -1826,7 +1840,6 @@ r_object_for(struct load_arg *arg, bool partial, int *ivp, VALUE extmod, int typ case TYPE_IVAR: { int ivar = TRUE; - v = r_object0(arg, true, &ivar, extmod); if (ivar) r_ivar(v, NULL, arg); v = r_leave(v, arg, partial); @@ -2019,7 +2032,10 @@ r_object_for(struct load_arg *arg, bool partial, int *ivp, VALUE extmod, int typ } rb_str_set_len(str, dst - ptr); } - v = r_entry0(rb_reg_new_str(str, options), idx, arg); + VALUE regexp = rb_reg_new_str(str, options); + rb_ivar_foreach(str, r_move_ivar, regexp); + + v = r_entry0(regexp, idx, arg); v = r_leave(v, arg, partial); } break; diff --git a/spec/ruby/core/marshal/shared/load.rb b/spec/ruby/core/marshal/shared/load.rb index 98fae44296893f..479c7477ec1775 100644 --- a/spec/ruby/core/marshal/shared/load.rb +++ b/spec/ruby/core/marshal/shared/load.rb @@ -720,6 +720,17 @@ new_obj_metaclass_ancestors[@num_self_class, 3].should == [Meths, UserRegexp, Regexp] end + + ruby_bug "#19439", ""..."3.3" do + it "restore the regexp instance variables" do + obj = Regexp.new("hello") + obj.instance_variable_set(:@regexp_ivar, [42]) + + new_obj = Marshal.send(@method, "\x04\bI/\nhello\x00\a:\x06EF:\x11@regexp_ivar[\x06i/") + new_obj.instance_variables.should == [:@regexp_ivar] + new_obj.instance_variable_get(:@regexp_ivar).should == [42] + end + end end describe "for a Float" do diff --git a/version.h b/version.h index 919aed6bb5a103..f32fd8a22300a1 100644 --- a/version.h +++ b/version.h @@ -11,7 +11,7 @@ # define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR #define RUBY_VERSION_TEENY 1 #define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR -#define RUBY_PATCHLEVEL 37 +#define RUBY_PATCHLEVEL 38 #include "ruby/version.h" #include "ruby/internal/abi.h"