From 6339cb70c3bcc54696e98c303dd4b26ed3d57afd Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Wed, 26 Apr 2023 14:17:27 +0200 Subject: [PATCH] marshal.c: shallow freeze user objects When `freeze: true` argument is passed. [Bug #19427] --- marshal.c | 10 +++++++++- spec/ruby/core/marshal/shared/load.rb | 16 +++++++--------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/marshal.c b/marshal.c index cdf25df5aa..712a40347f 100644 --- a/marshal.c +++ b/marshal.c @@ -2155,7 +2155,12 @@ r_object_for(struct load_arg *arg, bool partial, int *ivp, VALUE extmod, int typ marshal_compat_t *compat = (marshal_compat_t*)d; v = compat->loader(klass, v); } - if (!partial) v = r_post_proc(v, arg); + if (!partial) { + if (arg->freeze) { + OBJ_FREEZE(v); + } + v = r_post_proc(v, arg); + } } break; @@ -2180,6 +2185,9 @@ r_object_for(struct load_arg *arg, bool partial, int *ivp, VALUE extmod, int typ load_funcall(arg, v, s_mload, 1, &data); v = r_fixup_compat(v, arg); v = r_copy_ivar(v, data); + if (arg->freeze) { + OBJ_FREEZE(v); + } v = r_post_proc(v, arg); if (!NIL_P(extmod)) { if (oldclass) append_extmod(v, extmod); diff --git a/spec/ruby/core/marshal/shared/load.rb b/spec/ruby/core/marshal/shared/load.rb index 74e21995ec..57cd6b0d26 100644 --- a/spec/ruby/core/marshal/shared/load.rb +++ b/spec/ruby/core/marshal/shared/load.rb @@ -141,16 +141,14 @@ describe :marshal_load, shared: true do end ruby_bug "#19427", "3.1"..."3.3" do - ruby_bug "#19427", "3.1"..."3.4" do # https://bugs.ruby-lang.org/issues/19427#note-15 - it "returns frozen object having #_dump method" do - object = Marshal.send(@method, Marshal.dump(UserDefined.new), freeze: true) - object.should.frozen? - end + it "returns frozen object having #_dump method" do + object = Marshal.send(@method, Marshal.dump(UserDefined.new), freeze: true) + object.should.frozen? + end - it "returns frozen object responding to #marshal_dump and #marshal_load" do - object = Marshal.send(@method, Marshal.dump(UserMarshal.new), freeze: true) - object.should.frozen? - end + it "returns frozen object responding to #marshal_dump and #marshal_load" do + object = Marshal.send(@method, Marshal.dump(UserMarshal.new), freeze: true) + object.should.frozen? end it "returns frozen object extended by a module" do