summaryrefslogtreecommitdiff
path: root/spec/ruby
diff options
context:
space:
mode:
authorJean Boussier <jean.boussier@gmail.com>2021-09-18 15:34:15 +0200
committerJean Boussier <jean.boussier@gmail.com>2021-10-05 18:34:56 +0200
commitafcbb501ac17ba2ad5370ada5fd26e8dda9a5aaa (patch)
tree7316e197ec1f1097b334ad587ee58a58d9961b3f /spec/ruby
parent279b2b5b600f0bb16f7ebb08aa4a299cf7b023a8 (diff)
marshal.c Marshal.load accepts a freeze: true option.
Fixes [Feature #18148] When set, all the loaded objects are returned as frozen. If a proc is provided, it is called with the objects already frozen.
Diffstat (limited to 'spec/ruby')
-rw-r--r--spec/ruby/core/marshal/shared/load.rb94
1 files changed, 94 insertions, 0 deletions
diff --git a/spec/ruby/core/marshal/shared/load.rb b/spec/ruby/core/marshal/shared/load.rb
index 37c29d7cc6..e04a30c02f 100644
--- a/spec/ruby/core/marshal/shared/load.rb
+++ b/spec/ruby/core/marshal/shared/load.rb
@@ -19,6 +19,100 @@ describe :marshal_load, shared: true do
-> { Marshal.send(@method, kaboom) }.should raise_error(ArgumentError)
end
+ ruby_version_is "3.1" do
+ describe "when called with freeze: true" do
+ it "returns frozen strings" do
+ string = Marshal.send(@method, Marshal.dump("foo"), freeze: true)
+ string.should == "foo"
+ string.should.frozen?
+
+ utf8_string = "foo".encode(Encoding::UTF_8)
+ string = Marshal.send(@method, Marshal.dump(utf8_string), freeze: true)
+ string.should == utf8_string
+ string.should.frozen?
+ end
+
+ it "returns frozen arrays" do
+ array = Marshal.send(@method, Marshal.dump([1, 2, 3]), freeze: true)
+ array.should == [1, 2, 3]
+ array.should.frozen?
+ end
+
+ it "returns frozen hashes" do
+ hash = Marshal.send(@method, Marshal.dump({foo: 42}), freeze: true)
+ hash.should == {foo: 42}
+ hash.should.frozen?
+ end
+
+ it "returns frozen regexps" do
+ regexp = Marshal.send(@method, Marshal.dump(/foo/), freeze: true)
+ regexp.should == /foo/
+ regexp.should.frozen?
+ end
+
+ it "returns frozen objects" do
+ source_object = Object.new
+ source_object.instance_variable_set(:@foo, "bar")
+
+ object = Marshal.send(@method, Marshal.dump(source_object), freeze: true)
+ object.should.frozen?
+ object.instance_variable_get(:@foo).should.frozen?
+ end
+
+ it "does not freeze modules" do
+ Marshal.send(@method, Marshal.dump(Kernel), freeze: true)
+ Kernel.should_not.frozen?
+ end
+
+ it "does not freeze classes" do
+ Marshal.send(@method, Marshal.dump(Object), freeze: true)
+ Object.should_not.frozen?
+ end
+
+ describe "when called with a proc" do
+ it "call the proc with frozen objects" do
+ arr = []
+ s = 'hi'
+ s.instance_variable_set(:@foo, 5)
+ st = Struct.new("Brittle", :a).new
+ st.instance_variable_set(:@clue, 'none')
+ st.a = 0.0
+ h = Hash.new('def')
+ h['nine'] = 9
+ a = [:a, :b, :c]
+ a.instance_variable_set(:@two, 2)
+ obj = [s, 10, s, s, st, a]
+ obj.instance_variable_set(:@zoo, 'ant')
+ proc = Proc.new { |o| arr << o; o}
+
+ Marshal.send(
+ @method,
+ "\x04\bI[\vI\"\ahi\a:\x06EF:\t@fooi\ni\x0F@\x06@\x06IS:\x14Struct::Brittle\x06:\x06af\x060\x06:\n@clueI\"\tnone\x06;\x00FI[\b;\b:\x06b:\x06c\x06:\t@twoi\a\x06:\t@zooI\"\bant\x06;\x00F",
+ proc,
+ freeze: true,
+ )
+
+ arr.should == [
+ false, 5, "hi", 10, "hi", "hi", 0.0, false, "none", st,
+ :b, :c, 2, a, false, "ant", ["hi", 10, "hi", "hi", st, [:a, :b, :c]],
+ ]
+
+ arr.each do |obj|
+ obj.should.frozen?
+ end
+
+ Struct.send(:remove_const, :Brittle)
+ end
+
+ it "does not freeze the object returned by the proc" do
+ string = Marshal.send(@method, Marshal.dump("foo"), proc { |o| o.upcase }, freeze: true)
+ string.should == "FOO"
+ string.should_not.frozen?
+ end
+ end
+ end
+ end
+
describe "when called with a proc" do
ruby_bug "#18141", ""..."3.1" do
it "call the proc with fully initialized strings" do