Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JSON parsing of large numbers #156

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/com/adobe/serialization/json/JSON.as
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ package com.adobe.serialization.json
*
* @param s The JSON string representing the object
* @param strict Flag indicating if the decoder should strictly adhere
* to the JSON standard or not. The default of <code>true</code>
* to t he JSON standard or not. The default of <code>true</code>
* throws errors if the format does not match the JSON syntax exactly.
* Pass <code>false</code> to allow for non-properly-formatted JSON
* strings to be decoded with more leniancy.
Expand Down
15 changes: 15 additions & 0 deletions src/com/adobe/serialization/json/JSONTokenizer.as
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,14 @@ package com.adobe.serialization.json
*/
private const controlCharsRegExp:RegExp = /[\x00-\x1F]/;

/**
* The maximum number that can be represented accurately as a double
* in either AS3/ECMA languages.
*
* See http://stackoverflow.com/questions/4840482/javascript-integer-overflow
*/
private const MAX_DOUBLE:Number = Math.pow(2,53);

/**
* Constructs a new JSONDecoder to parse a JSON string
* into a native object.
Expand Down Expand Up @@ -520,6 +528,13 @@ package com.adobe.serialization.json
// convert the string to a number value
var num:Number = Number( input );

if ( num > MAX_DOUBLE )
{
// Special case for numbers largers than doubles that we can't accurately represent in AS3
// We treat these as a string instead.
return JSONToken.create( JSONTokenType.STRING, input );
}

if ( isFinite( num ) && !isNaN( num ) )
{
// the token for the number that we've read
Expand Down
22 changes: 22 additions & 0 deletions tests/src/com/adobe/serialization/json/JSONTest.as
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,28 @@ package com.adobe.serialization.json
expectParseError( "0xFF0033" );
}

/**
* Test decoding numbers that are larger than 2^52 and cannot
* be accurately decoded in Flash. We return them as strings.
*/
public function testLargeNumbers():void
{
// when this is cast to a number, it gets cast to 10100401822940524
var big:String = "{\"val\":10100401822940525}";

var decoded:Object = JSON.decode( big );

assertTrue( decoded.val is String );
assertTrue( decoded.val == "10100401822940525" );


var small:String = "{\"val\":100}";
decoded = JSON.decode( small );

assertTrue( decoded.val is Number );
assertTrue( decoded.val == 100 );
}

/**
* Non-strict mode allows for NaN as a valid token
*/
Expand Down