2010-11-17 15 views
14

json2.js es estricto y se requiere que todas las claves de objeto tengan doble comilla. Sin embargo, en la sintaxis de Javascript {"foo":"bar"} es equivalente a {foo:"bar"}.Analizando de forma segura una cadena JSON con las teclas sin comillas

Tengo un área de texto que acepta la entrada JSON del usuario y me gustaría "aliviar" la restricción al hacer doble cita de las teclas. He visto cómo json2.js valida una cadena JSON en cuatro etapas antes de que la evalúe. Pude agregar una quinta etapa para permitir claves no citadas y me gustaría saber si hay alguna implicancia de seguridad para esta lógica.

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

usted asume un objeto JavaScript literal es equivalente a JSON, lo que no lo es. – Stephen

+6

'{name:" Joe "}' es Javascript válido, pero es _invalid_ JSON. Además, no desea hackear 'json2.js' porque simplemente refleja cómo funciona el soporte nativo JSON de los navegadores. En Chrome, por ejemplo, 'JSON.parse()' sin 'json2.js' también se ahogaría en eso. Pero lo peor es que 'json2.js' no cargará nada si el navegador tiene soporte JSON nativo. Por lo tanto, se encontrará en una situación en la que los navegadores con soporte nativo JSON nunca verán este truco, porque en su lugar usa código nativo para analizarlo. –

+0

@Stephen Tienes razón. Tal vez debería volver a formular la pregunta como "Analizar de forma segura JavaScript Object Literal y convertir a JSON". – daepark

Respuesta

0

JSON no permite las teclas sin comillas. JSON es un subconjunto de la notación JavaScript, y eso no incluye claves sin comillas. Pasar claves sin comillas a casi cualquier analizador JSON probablemente arrojará un error o devolverá resultados "inesperados".

Esperanza esto ayuda

+3

Es cierto acerca de JSON, por supuesto, pero JavaScript permite claves sin comillas en literales de objetos. Es un poco problemático ya que no puedes usar guiones ni palabras reservadas sin comillas. Creo que el asker ya lo sabe, sin embargo. – JAL

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

que reemplazará cualquier comillas simples en el nombre del parámetro, y añadir los que faltan.

+5

Esto parece funcionar. Excepto que no manejó el guión bajo. Aquí hay una expresión regular actualizada: 'hash.replace (/ (['"])? ([A-zA-Z0-9 _] +) ([' "])?:/G, '" $ 2 ":');' –

+0

touche, gracias que fue un descuido –

+4

Esta respuesta está lejos de ser perfecta. Pruebe '{a: ['b', 'c']}' o '{a:" Nota: algo sucedió. "}' – powerboy

1

Pensé que sería útil contar con casos de prueba reales para resolver cualquier problema con esta implementación. He agregado un proyecto de github llamado JSOL con algunas pruebas. Por favor rellene gratis para agregar y encontrar problemas. Gracias.

https://github.com/daepark/JSOL

Cuestiones relacionadas