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.