med*_*iev 5 javascript parsing json
我注意到jQuery parseJSON基本上做了一个简单的正则表达式"检查":
parseJSON: function( data ) {
if ( typeof data !== "string" || !data ) {
return null;
}
// Make sure leading/trailing whitespace is removed (IE can't handle it)
data = jQuery.trim( data );
// Make sure the incoming data is actual JSON
// Logic borrowed from http://json.org/json2.js
if ( /^[\],:{}\s]*$/.test(data.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@")
.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]")
.replace(/(?:^|:|,)(?:\s*\[)+/g, "")) ) {
// Try to use the native JSON parser first
return window.JSON && window.JSON.parse ?
window.JSON.parse( data ) :
(new Function("return " + data))();
} else {
jQuery.error( "Invalid JSON: " + data );
}
},
Run Code Online (Sandbox Code Playgroud)
如果它通过了"检查",如果它是现代浏览器,则使用本机JSON解析器.否则,我假设对于像IE6这样的浏览器,会自动调用一个新函数并返回该对象.
问题1:由于这只是一个简单的正则表达式测试,这是不是容易出现某种模糊的边缘案例漏洞?对于那些至少不支持原生JSON解析的浏览器,我们真的不应该使用完整的解析器吗?
问题2:(new Function(" return " + data ))()相对于多少"更安全" eval("(" + text + ")")?
正如评论中提到的,jQuery 的 JSON 解析器直接从 json2.js 中“借用”了测试 JSON 字符串是否有效的逻辑。这使得它与最常见的非本机实现“一样安全”,无论如何,这是相当严格的:
\n\n// In the second stage, we run the text against regular expressions that look\n// for non-JSON patterns. We are especially concerned with \'()\' and \'new\'\n// because they can cause invocation, and \'=\' because it can cause mutation.\n// But just to be safe, we want to reject all unexpected forms.\n\n// We split the second stage into 4 regexp operations in order to work around\n// crippling inefficiencies in IE\'s and Safari\'s regexp engines. First we\n// replace the JSON backslash pairs with \'@\' (a non-JSON character). Second, we\n// replace all simple value tokens with \']\' characters. Third, we delete all\n// open brackets that follow a colon or comma or that begin the text. Finally,\n// we look to see that the remaining characters are only whitespace or \']\' or\n// \',\' or \':\' or \'{\' or \'}\'. If that is so, then the text is safe for eval.\n\n if (/^[\\],:{}\\s]*$/.\ntest(text.replace(/\\\\(?:["\\\\\\/bfnrt]|u[0-9a-fA-F]{4})/g, \'@\').\nreplace(/"[^"\\\\\\n\\r]*"|true|false|null|-?\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?/g, \']\').\nreplace(/(?:^|:|,)(?:\\s*\\[)+/g, \'\'))) {Run Code Online (Sandbox Code Playgroud)\n\n我不明白的是为什么 jQuery 在检查本机实现之前运行正则表达式/替换,无论如何,本机实现都会检查正确的 JSON 语法。似乎只有在本机实现不可用时才执行此操作会加快速度。
\n\nbobince在另一个问题中很好地回答了问题2 :
\n\n\n\n\n其实差别不大,但感觉 eval 比 new Function 更差 \xe2\x80\x98。不是在安全性方面\xe2\x80\x89\xe2\x80\x94\xe2\x80\x89它们在面对不受信任的输入时同样无用,但希望你的web应用程序不会返回不受信任的JSON字符串\xe2\ x80\x89\xe2\x80\x94\xe2\x80\x89 但是在语言级别的怪异方面,因此对优化产生了阻力。
\n
也可以查看Nick Craver 的回答,以获取 John Resig 的直接引用。
\n