From 8776f15b448ed88b1108e70f2de22f0b599818aa Mon Sep 17 00:00:00 2001 From: Prathamesh Sonpatki Date: Sun, 30 Oct 2016 14:12:43 +0530 Subject: [PATCH] Fix an issue with JSON encoding of "Infinity" and "NaN" values - When `as_json` returns `Infinity` or `NaN` as the value of any of the key, we don't used to call `as_json` on it as it was treated as primitive. - This used to pass `Infinity` or `NaN` to `JSON.generate` and Ruby used to throw an error for `Infinity/NaN not allowed in JSON.` - This patch changes the code to call `as_json` on these primitives so that they are converted to proper values before being passed to `JSON.generate`. - Fixes #26877. --- .../lib/active_support/json/encoding.rb | 2 +- activesupport/test/json/encoding_test.rb | 22 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/activesupport/lib/active_support/json/encoding.rb b/activesupport/lib/active_support/json/encoding.rb index cee731417f..6eb73723ad 100644 --- a/activesupport/lib/active_support/json/encoding.rb +++ b/activesupport/lib/active_support/json/encoding.rb @@ -84,7 +84,7 @@ module ActiveSupport when String EscapedString.new(value) when Numeric, NilClass, TrueClass, FalseClass - value + value.as_json when Hash Hash[value.map { |k, v| [jsonify(k), jsonify(v)] }] when Array diff --git a/activesupport/test/json/encoding_test.rb b/activesupport/test/json/encoding_test.rb index fc3af02cbc..e745f5e190 100644 --- a/activesupport/test/json/encoding_test.rb +++ b/activesupport/test/json/encoding_test.rb @@ -432,6 +432,28 @@ EXPECTED assert_equal '"foo"', ActiveSupport::JSON.encode(exception) end + class InfiniteNumber + def as_json(options = nil) + { "number" => 1.0 / 0 } + end + end + + def test_to_json_works_when_as_json_returns_infinite_number + expected = { number: nil }.to_json + assert_equal expected, InfiniteNumber.new.to_json + end + + class NaNNumber + def as_json(options = nil) + { "number" => 0.0 / 0 } + end + end + + def test_to_json_works_when_as_json_returns_NaN_number + expected = { number: nil }.to_json + assert_equal expected, NaNNumber.new.to_json + end + protected def object_keys(json_object)