diff --git a/lib/json/common.rb b/lib/json/common.rb index 090066012..fdbbeeeef 100644 --- a/lib/json/common.rb +++ b/lib/json/common.rb @@ -623,7 +623,8 @@ def dump(obj, anIO = nil, limit = nil, kwargs = nil) opts = JSON.dump_default_options opts = opts.merge(:max_nesting => limit) if limit opts = merge_dump_options(opts, **kwargs) if kwargs - result = generate(obj, opts) + sanitized_obj = make_json_compatible(obj) + result = generate(sanitized_obj, opts) if anIO anIO.write result anIO @@ -644,8 +645,24 @@ def merge_dump_options(opts, strict: NOT_SET) opts end + def make_json_compatible(obj) + case obj + when Hash + result = {} + obj.each do |k, v| + k = k.to_s unless String === k + result[k] = make_json_compatible(v) + end + result + when Array + obj.map { |v| make_json_compatible(v) } + else + obj + end + end + class << self - private :merge_dump_options + private :merge_dump_options, :make_json_compatible end end diff --git a/tests/json_generator_test.rb b/tests/json_generator_test.rb index 526bb8c1f..c3ee6c496 100755 --- a/tests/json_generator_test.rb +++ b/tests/json_generator_test.rb @@ -69,6 +69,10 @@ def test_dump_strict assert_equal '{}', dump({}, strict: true) end + def test_dump_duplicate_key_hash + assert_equal "{\"a\":5,\"c\":{\"b\":6}}", dump({ 'a' => 1, a: 5, c: { 'b' => 2, b: 6 } }) + end + def test_generate_pretty json = pretty_generate({}) assert_equal(<<'EOT'.chomp, json)