diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-04-22 08:09:44 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-04-22 08:09:44 +0000 |
commit | 67b180748b7e8e551f46a072013162db83ac703f (patch) | |
tree | da0c62f118ff38fb0a5e7992c4c06f409584b47d /marshal.c | |
parent | 16dc6c29554d9ea0cc3c01592646cceec827bba3 (diff) | |
download | ruby-67b180748b7e8e551f46a072013162db83ac703f.tar.gz |
marshal.c: fix marshal_load ivar
* marshal.c (r_object0): copy all instance variables not only generic
ivars, before calling post proc. [ruby-core:51163] [Bug #7627]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@40408 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'marshal.c')
-rw-r--r-- | marshal.c | 45 |
1 files changed, 33 insertions, 12 deletions
@@ -1335,7 +1335,7 @@ r_entry0(VALUE v, st_index_t num, struct load_arg *arg) } static VALUE -r_leave(VALUE v, struct load_arg *arg) +r_fixup_compat(VALUE v, struct load_arg *arg) { st_data_t data; if (st_lookup(arg->compat_tbl, v, &data)) { @@ -1349,6 +1349,12 @@ r_leave(VALUE v, struct load_arg *arg) st_delete(arg->compat_tbl, &key, 0); v = real_obj; } + return v; +} + +static VALUE +r_post_proc(VALUE v, struct load_arg *arg) +{ if (arg->proc) { v = rb_funcall(arg->proc, s_call, 1, v); check_load_arg(arg, s_call); @@ -1356,6 +1362,28 @@ r_leave(VALUE v, struct load_arg *arg) return v; } +static VALUE +r_leave(VALUE v, struct load_arg *arg) +{ + v = r_fixup_compat(v, arg); + v = r_post_proc(v, arg); + return v; +} + +static int +copy_ivar_i(st_data_t key, st_data_t val, st_data_t arg) +{ + rb_ivar_set((VALUE)arg, (ID)key, (VALUE)val); + return ST_CONTINUE; +} + +static VALUE +r_copy_ivar(VALUE v, VALUE data) +{ + rb_ivar_foreach(data, copy_ivar_i, (st_data_t)v); + return v; +} + static void r_ivar(VALUE obj, int *has_encoding, struct load_arg *arg) { @@ -1458,10 +1486,7 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod) rb_raise(rb_eArgError, "dump format error (unlinked)"); } v = (VALUE)link; - if (arg->proc) { - v = rb_funcall(arg->proc, s_call, 1, v); - check_load_arg(arg, s_call); - } + r_post_proc(v, arg); break; case TYPE_IVAR: @@ -1768,7 +1793,6 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod) VALUE klass = path2class(r_unique(arg)); VALUE oldclass = 0; VALUE data; - st_table *ivtbl; v = obj_alloc_by_klass(klass, arg, &oldclass); if (!NIL_P(extmod)) { @@ -1783,12 +1807,9 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod) data = r_object(arg); rb_funcall2(v, s_mload, 1, &data); check_load_arg(arg, s_mload); - v = r_leave(v, arg); - ivtbl = rb_generic_ivar_table(data); - if (ivtbl && ivtbl->num_entries) { - rb_check_frozen(v); - rb_copy_generic_ivar(v, data); - } + v = r_fixup_compat(v, arg); + v = r_copy_ivar(v, data); + v = r_post_proc(v, arg); if (!NIL_P(extmod)) { if (oldclass) append_extmod(v, extmod); rb_ary_clear(extmod); |