2010-11-17 10 views
14

json2.jsすべてのオブジェクトキーを二重引用符で囲む必要があります。ただし、JavaScriptの構文では{"foo":"bar"}{foo:"bar"}に相当します。引用符で囲まれていないキーでJSON文字列を安全に解析する

私はユーザーからのJSON入力を受け入れ、キーの二重引用符の制限を「緩和」したいと思うテキストエリアを持っています。 JSON文字列を検証する前に、json2.jsがJSON文字列を4段階で検証する方法を見てきました。引用符で囲まれていないキーを許可するために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); 
} 
+4

あなたはリテラルはそれがないJSON、と等価であるJavaScriptのオブジェクトを想定しています。 – Stephen

+6

'{name:" Joe "}'は有効なJavascriptですが、それは_invalid_ JSONです。また、json2.jsをハックしたくないのは、ブラウザのネイティブなJSONサポートがどのように動作するかを反映しているからです。たとえば、Chromeでは、 'JSON.parse()'に 'json2.js'を指定しないと、それもまた邪魔になります。しかし、ブラウザがネイティブJSONをサポートしている場合、 'json2.js'は何もロードしません。したがって、ネイティブコードを使用してJSONを解析するため、ネイティブJSONをサポートしているブラウザではこのハックは見られません。 –

+0

@Stephenそうです。 「JavaScript Object Literalを安全に解析してJSONに変換する」という質問を言い換えるべきでしょうか? – daepark

答えて

0

JSONでは、引用符で囲まれていないキーは使用できません。 JSONはJavaScript記法のサブセットであり、引用符で囲まれていないキーは含まれていません。引用符で囲まれていないキーをJSONパーサに渡すと、エラーが返されるか、「予期しない」結果が返される可能性があります。

希望これは、パラメータ名の任意の単一引用符を交換し、不足していることいずれかを追加します

+3

もちろんJSONについては真ですが、JavaScriptではオブジェクトリテラル内の引用符で囲まれていないキーを許可しています。ダッシュや予約語を引用符なしで使用できないため、ちょっとした問題です。しかし、私はそれをすでに知っていると思う。 – JAL

3
data.replace(/(['"])?([a-zA-Z0-9]+)(['"])?:/g, '"$2":'); 

に役立ちます。

+5

これはうまくいくようです。あなたがアンダースコアを処理できなかったことを除いて。これは更新された正規表現です: 'hash.replace(/(['"])?([a-zA-Z0-9 _] +)([' "])?:/ g、 '" $ 2 ":');' –

+0

touche、それは監視だったありがとう –

+4

この回答は完璧からは遠いです。 '{':[' b '、' c ']}'または '{a:"注:何かが起こった "}' – powerboy

1

私は、この実装の問題を洗い流すための実際のテストケースを持つと便利だと思いました。いくつかのテストでJSOLというgithubプロジェクトを追加しました。追加して問題を見つけるには、無料で記入してください。ありがとう。

https://github.com/daepark/JSOL

関連する問題