1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

[ruby/psych] Deduplicate hash keys if they're strings

https://github.com/ruby/psych/commit/0414982ffd
This commit is contained in:
Jean Boussier 2019-07-22 12:02:23 +02:00 committed by Nobuyoshi Nakada
parent 50076903ab
commit 6ca7dc69ef
2 changed files with 37 additions and 1 deletions

View file

@ -336,7 +336,7 @@ module Psych
SHOVEL = '<<'
def revive_hash hash, o
o.children.each_slice(2) { |k,v|
key = accept(k)
key = deduplicate(accept(k))
val = accept(v)
if key == SHOVEL && k.tag != "tag:yaml.org,2002:str"
@ -368,6 +368,28 @@ module Psych
hash
end
if String.method_defined?(:-@)
def deduplicate key
if key.is_a?(String)
# It is important to untaint the string, otherwise it won't
# be deduplicated into and fstring, but simply frozen.
-(key.untaint)
else
key
end
end
else
def deduplicate key
if key.is_a?(String)
# Deduplication is not supported by this implementation,
# but we emulate it's side effects
key.untaint.freeze
else
key
end
end
end
def merge_key hash, key, val
end

View file

@ -111,5 +111,19 @@ bar:
eoyml
assert_equal({"foo"=>{"hello"=>"world"}, "bar"=>{"hello"=>"world"}}, hash)
end
def test_key_deduplication
unless String.method_defined?(:-@) && (-("a" * 20)).equal?((-("a" * 20)))
skip "This Ruby implementation doesn't support string deduplication"
end
hashes = Psych.load(<<-eoyml)
---
- unique_identifier: 1
- unique_identifier: 2
eoyml
assert_same hashes[0].keys.first, hashes[1].keys.first
end
end
end