diff --git a/src/com/adobe/serialization/json/JSON.as b/src/com/adobe/serialization/json/JSON.as index 81b143c..d566844 100644 --- a/src/com/adobe/serialization/json/JSON.as +++ b/src/com/adobe/serialization/json/JSON.as @@ -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 true + * to t he JSON standard or not. The default of true * throws errors if the format does not match the JSON syntax exactly. * Pass false to allow for non-properly-formatted JSON * strings to be decoded with more leniancy. diff --git a/src/com/adobe/serialization/json/JSONTokenizer.as b/src/com/adobe/serialization/json/JSONTokenizer.as index 0072f6f..594312c 100644 --- a/src/com/adobe/serialization/json/JSONTokenizer.as +++ b/src/com/adobe/serialization/json/JSONTokenizer.as @@ -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. @@ -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 diff --git a/tests/src/com/adobe/serialization/json/JSONTest.as b/tests/src/com/adobe/serialization/json/JSONTest.as index 77d72c5..a539452 100644 --- a/tests/src/com/adobe/serialization/json/JSONTest.as +++ b/tests/src/com/adobe/serialization/json/JSONTest.as @@ -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 */