summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuheiNakasaka <[email protected]>2022-06-03 11:07:06 +0900
committerHiroshi SHIBATA <[email protected]>2024-10-18 11:28:13 +0900
commit57e1b64c812210f7bd703bc5d8d459d7a1197629 (patch)
tree6fd7941d4c5fd885d1cb5e1e49b81273efa39dba
parentc4d4c6b84683f0b5f9a84f29060a40823f3f5fe2 (diff)
[ruby/json] Fix behavior of trying to parse non-string objects
https://github.com/ruby/json/commit/e2e9936047
-rw-r--r--ext/json/lib/json/common.rb26
-rw-r--r--test/json/json_common_interface_test.rb22
2 files changed, 40 insertions, 8 deletions
diff --git a/ext/json/lib/json/common.rb b/ext/json/lib/json/common.rb
index 840c630fd5..403bd34b1d 100644
--- a/ext/json/lib/json/common.rb
+++ b/ext/json/lib/json/common.rb
@@ -20,11 +20,16 @@ module JSON
# 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 @@ module ::Kernel
# 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 c16f6ceaaf..f604d402f0 100644
--- a/test/json/json_common_interface_test.rb
+++ b/test/json/json_common_interface_test.rb
@@ -6,6 +6,13 @@ require 'tempfile'
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 @@ class JSONCommonInterfaceTest < Test::Unit::TestCase
'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 @@ class JSONCommonInterfaceTest < Test::Unit::TestCase
def test_JSON
assert_equal @json, JSON(@hash)
+ assert_equal @json, JSON(@hash_with_method_missing)
assert_equal @hash, JSON(@json)
end