json2.js 严格要求所有对象键都用双引号引起来。然而,在 Javascript 语法中
{"foo":"bar"}
相当于 {foo:"bar"}
。
我有一个文本区域,它接受用户的 JSON 输入,并希望“放松”对双引号键的限制。我研究了 json2.js 在评估 JSON 字符串之前如何分四个阶段验证它。我能够添加第五阶段以允许未加引号的密钥,并且想知道此逻辑是否存在任何安全隐患。
var data = '{name:"hello", age:"23"}';
// 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, ":") // EDITED: allow key:[array] by replacing with safe char ":"
/** everything up to this point is json2.js **/
/** this is the 5th stage where it accepts unquoted keys **/
.replace(/\w+\s*\:/g, ":")) ) { // EDITED: allow any alphanumeric key
console.log( (new Function("return " + data))() );
}
else {
throw( "Invalid JSON: " + data );
}
data.replace(/(['"])?([a-zA-Z0-9]+)(['"])?:/g, '"$2":');
这将替换参数名称上的任何单引号,并添加任何缺少的单引号。
JSON5.parse
JSON5 是 JSON 的超集,允许 ES5 语法,包括 unquoted 属性键。 JSON5 参考实现(
json5
npm 包)提供了一个 JSON5
对象,该对象具有与内置 JSON
对象相同的方法以及相同的参数和语义。
JSON5 被许多知名项目使用:
JSON5 于 2012 年启动,截至 2022 年,每周下载量超过 6500 万次,在 npm 上最依赖的软件包中排名前 0.1%,并已被 Chromium、Next.js、 Babel、Retool、WebStorm 等等。 MacOS 和 iOS 等 Apple 平台也原生支持它。
~ json5.org 主页
JSON 不允许不带引号的键。 JSON 是 JavaScript 表示法的子集,不包括不带引号的键。将不带引号的键传递给几乎任何 JSON 解析器都可能会抛出错误或返回“意外”结果。
希望这有帮助
“带有注释的 JSON”实际上是一个有效的 javascript,因此在 javascript 环境中解析它的最简单的本机方法就是像这样评估它
function evalJs(js) {
let fn = new Function("return (" + js + ")"),
res = fn()
return res;
}
let json5 = "{\n" +
"//////\n" +
"key: 5," +
"}"
let data = evalJs(json5)
console.info(data)
输出是
{ key: 5 }
!!!考虑安全风险——不要盲目评估
Object.defineProperty(String.prototype, "eval", {
get: function() {
let v;
eval('v =' + this);
return v;
}
});
var object = '{A:1,"B":[1,\'alfa\',"beta"]}'.eval