From e2e9936047ad1fbaa9cdf671a0652c80b61bcfc0 Mon Sep 17 00:00:00 2001 From: YuheiNakasaka Date: Fri, 3 Jun 2022 11:07:06 +0900 Subject: [PATCH] Fix behavior of trying to parse non-string objects --- lib/json/common.rb | 26 +++++++++++++++++-------- test/json/json_common_interface_test.rb | 22 +++++++++++++++++++++ 2 files changed, 40 insertions(+), 8 deletions(-) diff --git a/lib/json/common.rb b/lib/json/common.rb index 840c630fd..403bd34b1 100644 --- a/lib/json/common.rb +++ b/lib/json/common.rb @@ -20,11 +20,16 @@ class << self # ruby = [0, 1, nil] # JSON[ruby] # => '[0,1,null]' def [](object, opts = {}) - if object.respond_to? :to_str - JSON.parse(object.to_str, opts) - else - JSON.generate(object, opts) + if object.is_a?(String) + return JSON.parse(object, opts) + elsif object.respond_to?(:to_str) + str = object.to_str + if str.is_a?(String) + return JSON.parse(object.to_str, opts) + end end + + JSON.generate(object, opts) end # Returns the JSON parser class that is used by JSON. This is either @@ -693,11 +698,16 @@ def jj(*objs) # The _opts_ argument is passed through to generate/parse respectively. See # generate and parse for their documentation. def JSON(object, *args) - if object.respond_to? :to_str - JSON.parse(object.to_str, args.first) - else - JSON.generate(object, args.first) + if object.is_a?(String) + return JSON.parse(object, args.first) + elsif object.respond_to?(:to_str) + str = object.to_str + if str.is_a?(String) + return JSON.parse(object.to_str, args.first) + end end + + JSON.generate(object, args.first) end end diff --git a/test/json/json_common_interface_test.rb b/test/json/json_common_interface_test.rb index c16f6ceaa..f604d402f 100644 --- a/test/json/json_common_interface_test.rb +++ b/test/json/json_common_interface_test.rb @@ -6,6 +6,13 @@ class JSONCommonInterfaceTest < Test::Unit::TestCase include JSON + module MethodMissing + def method_missing(name, *args); end + def respond_to_missing?(name, include_private) + true + end + end + def setup @hash = { 'a' => 2, @@ -17,12 +24,26 @@ def setup 'h' => 1000.0, 'i' => 0.001 } + + @hash_with_method_missing = { + 'a' => 2, + 'b' => 3.141, + 'c' => 'c', + 'd' => [ 1, "b", 3.14 ], + 'e' => { 'foo' => 'bar' }, + 'g' => "\"\0\037", + 'h' => 1000.0, + 'i' => 0.001 + } + @hash_with_method_missing.extend MethodMissing + @json = '{"a":2,"b":3.141,"c":"c","d":[1,"b",3.14],"e":{"foo":"bar"},'\ '"g":"\\"\\u0000\\u001f","h":1000.0,"i":0.001}' end def test_index assert_equal @json, JSON[@hash] + assert_equal @json, JSON[@hash_with_method_missing] assert_equal @hash, JSON[@json] end @@ -129,6 +150,7 @@ def test_dump_should_modify_defaults def test_JSON assert_equal @json, JSON(@hash) + assert_equal @json, JSON(@hash_with_method_missing) assert_equal @hash, JSON(@json) end