From 40743b3d951b4822aac5e667c95dce790bcdc168 Mon Sep 17 00:00:00 2001 From: Aaron Brager Date: Tue, 17 Dec 2019 17:30:10 -0800 Subject: [PATCH 1/2] Add failing test for error on same key --- test/psych/test_hash.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/psych/test_hash.rb b/test/psych/test_hash.rb index 53747813..72ef06a6 100644 --- a/test/psych/test_hash.rb +++ b/test/psych/test_hash.rb @@ -92,6 +92,16 @@ def test_map assert_equal X, x.class end + def test_error_on_same_key + assert_raises(Psych::Exception) do + Psych.load <<-EOF + - + same_key: 'value' + same_key: 'value' + EOF + end + end + def test_self_referential @hash['self'] = @hash assert_cycle(@hash) From 469c7e3bc701d9b32ab8563107ac1f868df5733f Mon Sep 17 00:00:00 2001 From: Aaron Brager Date: Tue, 17 Dec 2019 17:34:59 -0800 Subject: [PATCH 2/2] Raise exception on duplicate keys --- lib/psych/handlers/document_stream.rb | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/lib/psych/handlers/document_stream.rb b/lib/psych/handlers/document_stream.rb index b77115d0..bf555ebf 100644 --- a/lib/psych/handlers/document_stream.rb +++ b/lib/psych/handlers/document_stream.rb @@ -18,6 +18,18 @@ def end_document implicit_end = !streaming? @last.implicit_end = implicit_end @block.call pop end + + def end_mapping + mapping = pop + keys = {} + mapping.children.each_slice(2) do |(key_scalar, _)| + next if key_scalar.is_a?(Psych::Nodes::Sequence) or key_scalar.is_a?(Psych::Nodes::Alias) or key_scalar.is_a?(Psych::Nodes::Mapping) + key = key_scalar.value + raise Psych::Exception, "Duplicate key #{key} exists on this level" if keys.key? key + keys[key] = nil + end + mapping + end end end end