Back to menu

JSON Parser

Preamble

JSON, unlike alternatives such as XML, is a pretty compact, simple and attractive way to encode some data. It gained some amount of popularity because it's trivial to decode JSON using JavaScript's eval(), which is 1) hackish because eval is an environment to execute instructions in, and JSON is a data, not instruction, format, and 2) slightly dubious because if the code comes from an untrusted source they can send you something like this:

"while (1) { alert('Hahaha!'); }"

and the worst thing is that your visitors will think it's your doing! (alternately they could quietly start binding extra event handlers to password inputs or start sending out HTTP requests over your visitors' internal networks).

The alternative to eval is to use a proper JSON decoder. But many JSON decoders are fairly fascistic on what they accept. The JSON spec is a lot stricter than JavaScript and this results in a lot of JSON being written which does not conform to the spec and eval being used instead of a real parser. There's no obvious reason for this strictness, so here is an error-tolerant parser (which does not use eval).

Technical Details

The parser is a simple recursive descent approach.

Two global mothods are provided:

readJson(json, errors) - takes a JSON string (as text) and returns an object, array, type, string, whatever the JSON string represented. Errors is an array which you may supply. After a call, the array will be populated with any errors or warnings that occurred in parsing.
writeJson(object) - writes an object or type (string, bool, number, null) to a JSON string.

This does not rely on jQuery!

Errors and Tolerance

Each error (as present in the errors array) is an object with the properties: level (0: warning or 1: error), lineno and charno (this might be either at the end of the erroneous text or at the start, it's not always trivial to get it consistent), and desc (a text description).

This parser will happily recognise (and raise warnings for) the following valid JavaScript but illegal JSON:

NOTE that 'undefined' is not allowed. The parser uses undefined interally (as an empty return value) to indicate a parse failure for a particular type. This could be abstracted away to distinguish between the "undefined" symbol and real failure, but really, your JSON shouldn't ever need to define a value as undefined! Simply omitting it is equivalent and more sensible.

This parser will grudgingly allow (and raise errors for) the following:

The parser should continue after encountering an error, but if an error is raised, it means data was probably lost. This is about the time that you should consider rewriting your JSON.

Some examples follow. They are arranged as as the original verbatim input string, followed by the parsed data (which has been re-encoded into a JSON string), followed by a list of warnings or errors that happened. The later examples show how problems are handled, or not, as the case may be.

Download

Download the: full source or minified source

Demo