[ruby/psych] Implement `freeze` option for Pysch.load

https://github.com/ruby/psych/commit/7dae24894d
This commit is contained in:
Jean Boussier 2019-07-24 16:01:20 -04:00 коммит произвёл Nobuyoshi Nakada
Родитель 4085c51a51
Коммит f641d78a6f
2 изменённых файлов: 27 добавлений и 7 удалений

Просмотреть файл

@ -32,16 +32,18 @@ module Psych
def accept target
result = super
return result if @domain_types.empty? || !target.tag
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
result = block.call value, result
end
end
result = deduplicate(result).freeze if @freeze
result
end
@ -341,7 +343,7 @@ module Psych
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
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

Просмотреть файл

@ -192,6 +192,22 @@ class TestPsych < Psych::TestCase
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