2010-11-17 7 views
14

json2.js ist streng vorgeschrieben, alle Objektschlüssel müssen doppelt zitiert werden. In Javascript-Syntax entspricht {"foo":"bar"} jedoch {foo:"bar"}.Sicheres Parsen einer JSON-Zeichenfolge mit nicht in Anführungszeichen gesetzten Schlüsseln

Ich habe eine Textarea, die JSON-Eingabe vom Benutzer akzeptiert und möchte die Einschränkung auf doppelte Anführungszeichen der Schlüssel "erleichtern". Ich habe mir angeschaut, wie json2.js eine JSON-Zeichenkette in vier Stufen validiert, bevor sie diese interpretiert. Ich war in der Lage, eine fünfte Stufe hinzuzufügen, um nicht aufgezählte Schlüssel zuzulassen, und würde gerne wissen, ob es Sicherheitseinflüsse auf diese Logik gibt.

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

Sie übernehmen eine wörtliche JavaScript Object zu JSON äquivalent ist, das es nicht ist. – Stephen

+6

'{name:" Joe "}' ist gültiges Javascript, aber es ist _invalid_ JSON. Außerdem möchten Sie nicht 'json2.js' hacken, weil es nur spiegelt, wie die native JSON-Unterstützung von Browsern funktioniert. In Chrome zum Beispiel würde 'JSON.parse()' ohne 'json2.js' auch daran ersticken. Aber schlimmer ist, dass 'json2.js' nichts lädt, wenn der Browser native JSON-Unterstützung hat. Sie werden also in einer Situation sein, in der Browser mit nativem JSON-Support diesen Hack niemals sehen, weil er stattdessen nativen Code verwendet, um ihn zu analysieren. –

+0

@Stephen Sie haben Recht. Vielleicht sollte ich die Frage wie "JavaScript-Objekt-Literal sicher analysieren und in JSON konvertieren" umformulieren? – daepark

Antwort

0

JSON erlaubt keine nicht-quoted Schlüssel. JSON ist eine Teilmenge der JavaScript-Notation, die keine nicht-angekreuzten Schlüssel enthält. Das Übergeben von nicht-quoted-Schlüsseln an fast jeden JSON-Parser wird wahrscheinlich einen Fehler auslösen oder "unerwartete" Ergebnisse liefern.

this helps

+3

Das stimmt zwar mit JSON, aber JavaScript erlaubt auch nicht angekreuzte Schlüssel in Objektliteralen. Es ist nur ein bisschen problematisch, da Sie Bindestriche oder reservierte Wörter nicht ohne Anführungszeichen verwenden können. Ich denke, der Fragesteller weiß das schon. – JAL

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

, dass jede einzelne Zitate auf den Parameternamen ersetzen wird, und fügen Sie alle, die fehlen.

+5

Das scheint zu funktionieren. Außer Sie konnten den Unterstrich nicht verarbeiten. Hier ist ein aktualisierter Regex: 'hash.replace (/ (['"])? ([A-zA-Z0-9 _] +) ([' "])?:/G, '" $ 2 ":');' –

+0

touche, danke das war ein Versehen –

+4

Diese Antwort ist bei weitem nicht perfekt. Versuchen Sie '{a: ['b', 'c']}' oder '{a:" Hinweis: etwas ist passiert. "}' – powerboy

1

Ich dachte, es wäre hilfreich, tatsächliche Testfälle zu haben, um irgendwelche Probleme mit dieser Implementierung zu beseitigen. Ich habe ein Github-Projekt namens JSOL mit einigen Tests hinzugefügt. Bitte füllen Sie kostenlos, um hinzuzufügen und Probleme zu finden. Vielen Dank.

https://github.com/daepark/JSOL