ruby-changes:61572
From: Jean <ko1@a...>
Date: Fri, 5 Jun 2020 11:50:17 +0900 (JST)
Subject: [ruby-changes:61572] f641d78a6f (master): [ruby/psych] Implement `freeze` option for Pysch.load
https://git.ruby-lang.org/ruby.git/commit/?id=f641d78a6f From f641d78a6fcf0b96c50077503a763478d0599fe5 Mon Sep 17 00:00:00 2001 From: Jean Boussier <jean.boussier@g...> Date: Wed, 24 Jul 2019 16:01:20 -0400 Subject: [ruby/psych] Implement `freeze` option for Pysch.load https://github.com/ruby/psych/commit/7dae24894d diff --git a/ext/psych/lib/psych/visitors/to_ruby.rb b/ext/psych/lib/psych/visitors/to_ruby.rb index 68452e5..a922f90 100644 --- a/ext/psych/lib/psych/visitors/to_ruby.rb +++ b/ext/psych/lib/psych/visitors/to_ruby.rb @@ -32,16 +32,18 @@ module Psych https://github.com/ruby/ruby/blob/trunk/ext/psych/lib/psych/visitors/to_ruby.rb#L32 def accept target result = super - return result if @domain_types.empty? || !target.tag - key = target.tag.sub(/^[!\/]*/, '').sub(/(,\d+)\//, '\1:') - key = "tag:#{key}" unless key =~ /^(?:tag:|x-private)/ + unless @domain_types.empty? || !target.tag + key = target.tag.sub(/^[!\/]*/, '').sub(/(,\d+)\//, '\1:') + key = "tag:#{key}" unless key =~ /^(?:tag:|x-private)/ - if @domain_types.key? key - value, block = @domain_types[key] - return block.call value, result + if @domain_types.key? key + value, block = @domain_types[key] + result = block.call value, result + end end + result = deduplicate(result).freeze if @freeze result end @@ -341,7 +343,7 @@ module Psych https://github.com/ruby/ruby/blob/trunk/ext/psych/lib/psych/visitors/to_ruby.rb#L343 key = accept(k) if @symbolize_names key = key.to_sym - else + elsif !@freeze key = deduplicate(key) end val = accept(v) @@ -378,6 +380,8 @@ module Psych https://github.com/ruby/ruby/blob/trunk/ext/psych/lib/psych/visitors/to_ruby.rb#L380 if RUBY_VERSION < '2.7' def deduplicate key if key.is_a?(String) + # It is important to untaint the string, otherwise it won't + # be deduplicated into an fstring, but simply frozen. -(key.untaint) else key diff --git a/test/psych/test_psych.rb b/test/psych/test_psych.rb index eeadc86..8fd9d27 100644 --- a/test/psych/test_psych.rb +++ b/test/psych/test_psych.rb @@ -192,6 +192,22 @@ class TestPsych < Psych::TestCase https://github.com/ruby/ruby/blob/trunk/test/psych/test_psych.rb#L192 assert_equal({ 'hello' => 'world' }, got) end + def test_load_freeze + data = Psych.load("--- {foo: ['a']}", freeze: true) + assert_predicate data, :frozen? + assert_predicate data['foo'], :frozen? + assert_predicate data['foo'].first, :frozen? + end + + def test_load_freeze_deduplication + unless String.method_defined?(:-@) && (-("a" * 20)).equal?((-("a" * 20))) + skip "This Ruby implementation doesn't support string deduplication" + end + + data = Psych.load("--- ['a']", freeze: true) + assert_same 'a', data.first + end + def test_load_default_fallback assert_equal false, Psych.load("") end -- cgit v0.10.2 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/