2010-11-17 16 views
14

json2.js è rigorosa e richiede che tutte le chiavi dell'oggetto siano doppiamente citate. Tuttavia, nella sintassi Javascript {"foo":"bar"} equivale a {foo:"bar"}.L'analisi sicura di una stringa JSON con chiavi non quotate

Ho una textarea che accetta l'input JSON dall'utente e vorrebbe "facilitare" la limitazione sulla doppia quotatura dei tasti. Ho esaminato in che modo json2.js convalida una stringa JSON in quattro fasi prima di evitarlo. Sono stato in grado di aggiungere una quinta fase per consentire le chiavi non quotate e vorrei sapere se ci sono implicazioni di sicurezza per questa logica.

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

utente si assume un oggetto JavaScript letterale equivale a JSON, che non lo è. – Stephen

+6

'{nome:" Joe "}' è Javascript valido, ma è _invalid_ JSON. Inoltre non vuoi hackerare 'json2.js' perché rispecchia solo il funzionamento del supporto JSON nativo dei browser. In Chrome, ad esempio, 'JSON.parse()' senza 'json2.js' potrebbe soffocare anche su quello. Ma peggio è che 'json2.js' non caricherà nulla se il browser ha il supporto JSON nativo. Quindi ti troverai in una situazione in cui i browser con JSON suport nativo non vedranno mai questo hack, perché usa il codice nativo per analizzarlo. –

+0

@Stephen Hai ragione. Forse dovrei riformulare la domanda come "Analizzare in modo sicuro l'oggetto JavaScript letterale e convertirlo in JSON"? – daepark

risposta

0

JSON non consente chiavi non quotate. JSON è un sottoinsieme della notazione JavaScript e questo non include le chiavi non quotate. Passare le chiavi non quotate a qualsiasi parser JSON probabilmente genererà un errore o restituirà risultati "imprevisti".

Spero che questo aiuti

+3

Vero su JSON, ovviamente, ma JavaScript consente le chiavi non quotate nei letterali degli oggetti. È solo un po 'problematico in quanto non è possibile utilizzare trattini o parole riservate senza virgolette. Penso che il richiedente lo sappia già, comunque. – JAL

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

che andrà a sostituire uno stesso citazioni sul nome del parametro, e aggiungere qualsiasi che mancano.

+5

Sembra funzionare. Tranne che non sei riuscito a gestire il trattino basso. Ecco una espressione regolare aggiornata: 'hash.replace (/ (['"])? ([A-zA-Z0-9 _] +) ([' "])?:/G, '" $ 2 ":');' –

+0

touche, grazie che era una svista –

+4

Questa risposta è tutt'altro che perfetta. Prova '{a: ['b', 'c']}' o '{a:" Nota: è successo qualcosa. "}' – powerboy

1

Ho pensato che sarebbe stato utile avere casi di test effettivi per eliminare eventuali problemi con questa implementazione. Ho aggiunto un progetto github chiamato JSOL con alcuni test. Si prega di compilare gratuitamente per aggiungere e trovare problemi. Grazie.

https://github.com/daepark/JSOL

Problemi correlati