TL;DR: Adding any non-built-in functions to Array.prototype AND Function.prototype will cause the IE8 native JSON parser to get a stack overflow when parsing any JSON that contains an array, but only when you also pass a reviver function into JSON.parse().
This started out as a question, but I answered my own original question, so now I'll ask: can anyone think of a work-around for this IE8 bug that doesn't involve eliminating all JS libraries that modify Array.prototype and Function.prototype?
Original question:
I have about 13k of JSON data to parse. The structure of the data is an object with a single value that is a nested array.
{ 'value':[[ stuff ], [ more stuff], [ etc ]] }
I'm using json2.js, which defers to the browser native JSON.parse when available. I'm passing a reviver function into JSON.parse to handle dates properly. When IE8 is in IE7 emulation mode (which causes it to use the script-based json2.js parser) everything works fine. When IE8 is in IE8 mode (which causes it to use the browser-native JSON parser) it blows up with an "out of stack space" error. Firefox and Chrome, of course, work just fine with their browser-native JSON parsers.
I've narrowed it down to this: if I pass even a do-nothing reviver function into JSON.parse, the IE8 native parser gets the stack overflow. If I pass in no reviver function, the IE8 native parser works fine, except it doesn't parse dates correctly.
// no error:
JSON.parse(stuff);
// "out of stack space" error:
JSON.parse(stuff, function(key, val) { return val; });
I'm going to play with my JSON data, to see if less data or less nesting of the data can avoid the error, but I was wondering if anyone had seen this before, or had any other suggested work-arounds. IE8 is slow enough already, it would be a shame to disable native JSON for that browser because of this bug.
UPDATE: In other cases, with different JSON data, I'm getting a javascript error "$lineinfo is undefined" when I use the IE8 native parser with a reviver function, and no error if I use no reviver function. The string "$lineinfo" does not appear anywhere in any of my source code.
UPDATE 2: Actually, this problem seems to be caused by Prototype 1.6.0.3. I was unable to reproduce it in an isolated test page until I added in the Prototype library.
UPDATE 3:
The reason prototype.js breaks the IE8 native JSON parser is this: Adding any non-built-in functions to Array.prototype AND Function.prototype will cause the IE8 native JSON parser to get a stack overflow when parsing any JSON that contains an array, but only when you also pass a reviver function into JSON.parse().
The Prototype library adds functions to both Array.prototype and Function.prototype, but this applies equally to any other library that does the same thing. This bug in the IE JSON parser is exposed by Prototype and Ext, but not jQuery. I haven't tested any other frameworks.
Here is a completely stand-alone reproduction of the problem. If you remove the Function.prototype line, or the Array.prototype line, or remove the array from the JSON string, you won't get the "out of stack space" error.
<!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>
See Question&Answers more detail:
os