Natywny błąd JSON.parse w IE8 powoduje przepełnienie stosu

TL; DR:Dodanie funkcji nie wbudowanych do Array.prototype AND Function.prototype spowoduje, że natywny parser JSON IE8 uzyska przepełnienie stosu podczas analizowania dowolnego JSON zawierającego tablicę, ale tylko wtedy, gdy przekażesz również funkcję reviver do JSON.parse ().

Zaczęło się od pytania, ale odpowiedziałem na moje własne pierwotne pytanie, więc teraz zapytam: czy ktoś może pomyśleć o obejściu tego błędu IE8, który nie wymaga eliminacji wszystkich bibliotek JS, które modyfikują Array.prototype i Function .prototyp?

Oryginalne pytanie:

Mam do przeanalizowania około 13k danych JSON. Struktura danych jest obiektem z pojedynczą wartością, która jest tablicą zagnieżdżoną.

{ 'value':[[ stuff ], [ more stuff], [ etc ]] }

Korzystam z json2.js, który odracza się do rodzimej przeglądarki JSON.parse, jeśli jest dostępna. Przekazuję funkcję reviver do JSON.parse, aby poprawnie obsługiwać daty. Gdy IE8 jest w trybie emulacji IE7 (co powoduje, że używa parsera json2.js opartego na skryptach), wszystko działa dobrze. Gdy IE8 jest w trybie IE8 (co powoduje, że używa rodzimego parsera JSON w przeglądarce), wysadza się z błędem „poza stosem”. Firefox i Chrome, oczywiście, działają dobrze z ich rodzimymi przeglądarkami JSON.

Zawęziłem to do tego: jeśli przekazam nawet funkcję reanimatora do JSON.parse, natywny parser IE8 pobiera przepełnienie stosu. Jeśli nie przekażę żadnej funkcji reviver, natywny parser IE8 działa dobrze, z wyjątkiem tego, że nie analizuje poprawnie dat.

// no error:
JSON.parse(stuff);

// "out of stack space" error:
JSON.parse(stuff, function(key, val) { return val; });

Będę się bawił z moimi danymi JSON, aby zobaczyć, czy mniej danych lub mniej zagnieżdżonych danych może uniknąć błędu, ale zastanawiałem się, czy ktoś widział to wcześniej, lub miał inne sugerowane obejścia. IE8 jest już wystarczająco powolny, wstydem byłoby wyłączenie rodzimego JSON dla tej przeglądarki z powodu tego błędu.

AKTUALIZACJA: W innych przypadkach, z różnymi danymi JSON, otrzymuję błąd javascript „$ lineinfo jest niezdefiniowany”, gdy używam natywnego parsera IE8 z funkcją reviver, i bez błędu, jeśli nie używam funkcji reviver. Ciąg „$ lineinfo” nie pojawia się w żadnym miejscu mojego kodu źródłowego.

UPDATE 2: Właściwie problem ten wydaje się być spowodowany przez Prototype 1.6.0.3. Nie byłem w stanie odtworzyć go na izolowanej stronie testowej, dopóki nie dodałem go do biblioteki Prototype.

AKTUALIZACJA 3:

Powodem, dla którego prototype.js łamie natywny parser JSON IE8, jest: Dodanie do Array.prototype i Function.prototype dowolnych funkcji niewbudowanych spowoduje, że natywny analizator składni JSON IE8 przepełni stos podczas analizowania dowolnego JSON zawierającego tablicę , ale tylko wtedy, gdy przekażesz również funkcję reviver do JSON.parse ().

Biblioteka Prototype dodaje funkcje zarówno do Array.prototype, jak i Function.prototype, ale dotyczy to również każdej innej biblioteki, która robi to samo. Ten błąd w parserze IE JSON jest ujawniany przez Prototype i Ext, ale nie przez jQuery. Nie testowałem żadnych innych frameworków.

Oto całkowicie samodzielna reprodukcja problemu. Jeśli usuniesz linię Function.prototype lub linię Array.prototype lub usuniesz tablicę z łańcucha JSON, nie otrzymasz błędu „out of stack space”.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
<script type="text/javascript">

Function.prototype.test1 = function() { };
Array.prototype.test2 = function() { };

window.onload = function()
{
    alert(JSON.parse('{ "foo": [1,2,3] }', function(k,v) { return v; }));
}

</script>
</head>
<body>

</body>
</html>

questionAnswers(6)

yourAnswerToTheQuestion