Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.Sign up
Fix an issue with JSON encoding of "Infinity" and "NaN" values #26933
- 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.
Removing `as_json` here revealed that these tests failed because they return a non-json compliant value of NaNNumber and InfinitNumber. While we've supported this for awhile one of the issues with this support is that once we hit `jsonify` all the values _should_ already be json-compliant values. These tests I removed were added in #26933 - but in the comments on that PR they were supposed to be deprecated and removed in the next cycle - but that work never happened. See #26933 (comment) We want to remove this `as_json` here because Rails JSON is very slow. One of the reasons it's slow is because in some cases we actually loop over the JSON we're parsing 3 times! Here are the passes: 1. Call as_json on a tree of objects 1a. Special objects pass the options down. These are Object, Struct, Enumerable, Array, Hash 1b. This first pass eliminates Structs, Enumerables, and Objects Structs replaced with hashes, Enumerables -> Arrays, Objects -> Hash 1c. New tree contains only: String, Number, Hash, Array, nil, true, false 2. Tree is walked again 2a. Convert Strings to EscapedStrings 2b. Can retun bad values from as_json (like the infinity and nan) 3. Convert to json By removing this `as_json` we reduce one of the passes for this case. The argument here is that the first pass should never have returned a bad value so we shouldn't have to walk those values a second time - the value should be `nil` (which it what it will be on pass 3). [Eileen M. Uchitelle & Aaron Patterson]
@DaniG2k - Rails 4.2 hasn't been supported for bug fixes in a long time. It's only supported for security releases. If you look at the commit c85d305 you can see it's included in tags 5.1.0.beta1 and up. This change required a deprecation before it was merged and was a change in behavior so we couldn't backport it at the time to 4.2 and definitely can't now.
Just in case it's not on your radar, Rails 4.2 will soon no longer be supported for even security fixes so we recommend you upgraded ASAP. Also gotta say Rails 6.0 is prettty nice.