diff options
author | Richard Gibson <richard.gibson@gmail.com> | 2013-11-04 23:36:15 -0500 |
---|---|---|
committer | Richard Gibson <richard.gibson@gmail.com> | 2013-11-12 00:07:28 -0500 |
commit | 60a6178131afec97b68c9a45bc24459f7b8bd905 (patch) | |
tree | 81289bd251c2bc117eb0020e05c65573010cdacb /src/ajax | |
parent | ef7f8f1ead0d80e53cde0a2c7d6af289bd182ce0 (diff) | |
download | jquery-60a6178131afec97b68c9a45bc24459f7b8bd905.tar.gz jquery-60a6178131afec97b68c9a45bc24459f7b8bd905.zip |
Fix #14492: More correct jQuery.parseJSON. Close gh-1419.
Diffstat (limited to 'src/ajax')
-rw-r--r-- | src/ajax/parseJSON.js | 53 |
1 files changed, 31 insertions, 22 deletions
diff --git a/src/ajax/parseJSON.js b/src/ajax/parseJSON.js index 735015c9f..69b5c837d 100644 --- a/src/ajax/parseJSON.js +++ b/src/ajax/parseJSON.js @@ -2,39 +2,48 @@ define([ "../core" ], function( jQuery ) { -var rvalidchars = /^[\],:{}\s]*$/, - rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, - rvalidescape = /\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g, - rvalidtokens = /"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g; +var rvalidtokens = /(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g; jQuery.parseJSON = function( data ) { // Attempt to parse using the native JSON parser first if ( window.JSON && window.JSON.parse ) { - return window.JSON.parse( data ); + // Support: Android 2.3 + // Workaround failure to string-cast null input + return window.JSON.parse( data + "" ); } - if ( data === null ) { - return data; - } - - if ( typeof data === "string" ) { + var requireNonComma, + depth = null, + str = jQuery.trim( data + "" ); - // Make sure leading/trailing whitespace is removed (IE can't handle it) - data = jQuery.trim( data ); + // Guard against invalid (and possibly dangerous) input by ensuring that nothing remains + // after removing valid tokens + return str && !jQuery.trim( str.replace( rvalidtokens, function( token, comma, open, close ) { - if ( data ) { - // Make sure the incoming data is actual JSON - // Logic borrowed from http://json.org/json2.js - if ( rvalidchars.test( data.replace( rvalidescape, "@" ) - .replace( rvalidtokens, "]" ) - .replace( rvalidbraces, "")) ) { + // Force termination if we see a misplaced comma + if ( requireNonComma && comma ) { + depth = 0; + } - return ( new Function( "return " + data ) )(); - } + // Perform no more replacements after returning to outermost depth + if ( depth === 0 ) { + return token; } - } - jQuery.error( "Invalid JSON: " + data ); + // Commas must not follow "[", "{", or "," + requireNonComma = open || comma; + + // Determine new depth + // array/object open ("[" or "{"): depth += true - false (increment) + // array/object close ("]" or "}"): depth += false - true (decrement) + // other cases ("," or primitive): depth += true - true (numeric cast) + depth += !close - !open; + + // Remove this token + return ""; + }) ) ? + ( Function( "return " + str ) )() : + jQuery.error( "Invalid JSON: " + data ); }; return jQuery.parseJSON; |