2010-07-13 3 views
5

я заметил, что JQuery parseJSON в основном делает простой регулярное выражение «проверить»:Должны использоваться методы parseJSON/getJSON jQuery?

parseJSON: function(data) { 
    if (typeof data !== "string" || !data) { 
     return null; 
    } 

    // Make sure leading/trailing whitespace is removed (IE can't handle it) 
    data = jQuery.trim(data); 

    // 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, ""))) { 

     // Try to use the native JSON parser first 
     return window.JSON && window.JSON.parse ? 
      window.JSON.parse(data) : 
      (new Function("return " + data))(); 

    } else { 
     jQuery.error("Invalid JSON: " + data); 
    } 
}, 

Если она проходит, что «чек», и если это современный браузер используется родной JSON парсер. В противном случае я предполагаю, что для браузера, такого как IE6, новая функция автоматически вызывается и возвращает объект.

Вопрос # 1: Поскольку это простой тест регулярных выражений, разве это не связано с каким-то неясным краевым эксплойтом? Разве мы не должны использовать полноразмерный парсер для браузеров, которые, по крайней мере, не поддерживают собственный JSON-анализ?

Вопрос №2: Насколько «безопаснее» (new Function(" return " + data))() в отличие от eval("(" + text + ")")?

ответ

3

Как упоминалось в комментариях, JSON-парсер jQuery «заимствует» логику, которая проверяет правильность строки JSON, прямо из json2.js. Это делает его «безопасным» в качестве наиболее распространенных неродного реализации, что является довольно строгим в любом случае:

// In the second stage, we run the text against regular expressions that look 
// for non-JSON patterns. We are especially concerned with '()' and 'new' 
// because they can cause invocation, and '=' because it can cause mutation. 
// But just to be safe, we want to reject all unexpected forms. 

// We split the second stage into 4 regexp operations in order to work around 
// crippling inefficiencies in IE's and Safari's regexp engines. First we 
// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we 
// replace all simple value tokens with ']' characters. Third, we delete all 
// open brackets that follow a colon or comma or that begin the text. Finally, 
// we look to see that the remaining characters are only whitespace or ']' or 
// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. 

      if (/^[\],:{}\s]*$/. 
test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@'). 
replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']'). 
replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {

То, что я не понимаю, почему JQuery работает регулярное выражение/заменяет перед проверкой для собственной реализации что в любом случае проверяет правильную грамматику JSON. Похоже, что это ускорит выполнение только этого, если родная реализация недоступна.

Вопрос 2 в другом вопросе answered very well by bobince:

Это не очень большая разница, но такое ощущение, что Eval является «хуже», чем новая функция. Не с точки зрения безопасности - они одинаково бесполезны перед лицом ненадежного ввода, но, надеюсь, ваш webapp не возвращает ненадежные строки JSON, а с точки зрения странности на уровне языка и, следовательно, устойчивости к оптимизации.

Отъезд Nick Craver's answer там также для прямой цитаты от Джона Ресига.

0

Метод JSON.parse является самым безопасным. Это определяется, когда вы включаете json2.js из http://www.json.org/js.html и автоматически используется parseJSON/getJSON. Он анализирует вместо выполнения разметки JSON.

+3

json2.js будет использовать одно и то же регулярное выражение, а затем 'eval', если родной JSON недоступен. –

+0

Отмечено. Спасибо за разъяснения. – spoulson

Смежные вопросы