From 365286665777ef7a12b87bff3a9079bb6311c0cb Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Thu, 9 May 2024 14:21:17 +0200 Subject: [PATCH] JSON::Pure fix strict mode Followup: https://github.com/flori/json/pull/519 Fix: https://github.com/flori/json/issues/584 --- lib/json/pure/generator.rb | 8 +++++--- tests/json_generator_test.rb | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/lib/json/pure/generator.rb b/lib/json/pure/generator.rb index c85222cc..ad937138 100644 --- a/lib/json/pure/generator.rb +++ b/lib/json/pure/generator.rb @@ -219,7 +219,9 @@ def script_safe? @script_safe end - # Returns true, if forward slashes are escaped. Otherwise returns false. + # Returns true, if strict mode is enabled. Otherwise returns false. + # Strict mode only allow serializing JSON native types: Hash, Array, + # String, Integer, Float, true, false and nil. def strict? @strict end @@ -354,7 +356,7 @@ def json_transform(state) result << delim unless first result << state.indent * depth if indent result = "#{result}#{key.to_s.to_json(state)}#{state.space_before}:#{state.space}" - if state.strict? + if state.strict? && !(false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value) raise GeneratorError, "#{value.class} not allowed in JSON" elsif value.respond_to?(:to_json) result << value.to_json(state) @@ -397,7 +399,7 @@ def json_transform(state) each { |value| result << delim unless first result << state.indent * depth if indent - if state.strict? + if state.strict? && !(false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value) raise GeneratorError, "#{value.class} not allowed in JSON" elsif value.respond_to?(:to_json) result << value.to_json(state) diff --git a/tests/json_generator_test.rb b/tests/json_generator_test.rb index 526bb8c1..d88de374 100755 --- a/tests/json_generator_test.rb +++ b/tests/json_generator_test.rb @@ -67,6 +67,25 @@ def test_dump_unenclosed_hash def test_dump_strict assert_equal '{}', dump({}, strict: true) + + assert_equal '{"array":[42,4.2,"forty-two",true,false,null]}', dump({ + "array" => [42, 4.2, "forty-two", true, false, nil] + }, strict: true) + + assert_equal '{"int":42,"float":4.2,"string":"forty-two","true":true,"false":false,"nil":null,"hash":{}}', dump({ + "int" => 42, + "float" => 4.2, + "string" => "forty-two", + "true" => true, + "false" => false, + "nil" => nil, + "hash" => {}, + }, strict: true) + + assert_equal '[]', dump([], strict: true) + + assert_equal '42', dump(42, strict: true) + assert_equal 'true', dump(true, strict: true) end def test_generate_pretty