json2.js

Today I attended Wakate IT Benkyou-kai (in English, "Young IT Study Meetup"?). We read Secrets of the JavaScript Ninja and today's chapter is "Code Evaluation". This book contains many real-world examples. We saw Caja, Prototype, json2.js, base2, Packer, Screw.Unit, Processing.js and Objective-J.

For me, today's most striking code is json2.js. It has eval-based JSON parser and prevent unsafe code evaluation by an regular expression. (Note: real code is well-commented. You can see it at GitHub.)

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, ''))) {

    j = eval('(' + text + ')');

Huh?

Okay, let's try on WebKit's console. First pattern works like so:

> '{ "key": ["value\\n"] }'
"{ "key": ["value\n"] }"
> '{ "key": ["value\\n"] }'.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
"{ "key": ["value@"] }"

Second pattern works like so:

> '{ "key": ["value@"] }'.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']');
"{ ]: []] }"

Third pattern works like so:

> "{ ]: []] }".replace(/(?:^|:|,)(?:\s*\[)+/g, '')
"{ ]]] }"

Last but not least, can it be matched with /^[\],:{}\s]*$/?

> /^[\],:{}\s]*$/.test('{ ]]] }')
true

Great! We can pass the original string to eval() safely.

json2.js is implemented by Douglas Crockford, the designer of JSON. However, if I design JSON, I can't implement my safety checker like Douglas's. I'm not Chuck Norris.