简体   繁体   English

使用不带引号的键安全地解析 JSON 字符串

[英]Safely parsing a JSON string with unquoted keys

json2.js is strict requiring all object keys be double-quoted. json2.js严格要求所有对象键都用双引号引起来。 However, in Javascript syntax {"foo":"bar"} is equivalent to {foo:"bar"} .但是,在 Javascript 语法中{"foo":"bar"}等效于{foo:"bar"}

I have a textarea that accepts JSON input from the user and would like to "ease" the restriction on double quoting the keys.我有一个 textarea 接受来自用户的 JSON 输入,并希望“放宽”对双引号键的限制。 I've looked at how json2.js validates a JSON string in four stages before it evals it.我已经查看了 json2.js 如何在对 JSON 字符串进行评估之前分四个阶段验证它。 I was able to add a 5th stage to allow unquoted keys and would like to know if there are any security implications to this logic.我能够添加第 5 个阶段以允许未引用的键,并想知道此逻辑是否存在任何安全隐患。

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":');

这将替换参数名称上的任何单引号,并添加任何缺少的单引号。

I thought it would be helpful to have actual test cases to flush out any issues with this implementation.我认为有实际的测试用例来解决这个实现的任何问题会很有帮助。 I've added a github project called JSOL with some tests.我添加了一个名为 JSOL 的 github 项目,并进行了一些测试。 Please fill free to add to it and find issues.请填写免费添加到它并发现问题。 Thanks.谢谢。

https://github.com/daepark/JSOL https://github.com/daepark/JSOL

JSON does not allow unquoted keys. JSON 不允许不带引号的键。 JSON is a subset of JavaScript notation, and that does not include unquoted keys. JSON 是 JavaScript 符号的一个子集,不包括未加引号的键。 Passing unquoted keys to just about any JSON parser will likely throw an error or return "unexpected" results.将未加引号的键传递给几乎任何 JSON 解析器都可能会引发错误或返回“意外”结果。

Hope this helps希望这可以帮助

Use JSON5.parse使用JSON5.parse

JSON5 is a superset of JSON that allows ES5 syntax, including unquoted property keys. JSON5是 JSON 的超集,它允许使用 ES5 语法,包括不带引号的属性键。 The JSON5 reference implementation ( json5 npm package ) provides a JSON5 object that has the same methods with the same args and semantics as the built-in JSON object. JSON5 参考实现( json5 npm 包)提供了一个JSON5对象,该对象具有与内置JSON对象相同的方法和相同的参数和语义。

"JSON with comments" is actually a valid javascript, therefore in javascript environment the simplest native way to parse it is just evaluate it like this “带注释的 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)

Output is输出是

{ key: 5 }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM