2 Copyright (c) 2005 JSON.org
4 Permission is hereby granted, free of charge, to any person obtaining a copy
5 of this software and associated documentation files (the "Software"), to deal
6 in the Software without restriction, including without limitation the rights
7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 copies of the Software, and to permit persons to whom the Software is
9 furnished to do so, subject to the following conditions:
11 The Software shall be used for Good, not Evil.
13 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 The global object JSON contains two methods.
25 JSON.stringify(value) takes a JavaScript value and produces a JSON text.
26 The value must not be cyclical.
28 JSON.parse(text) takes a JSON text and produces a JavaScript value. It will
29 return false if there is an error.
31 2008-10-10: New regular expressions copied in from the new json2.js file on http://json.org (released into the public domain), work better on Safari and IE for more complicated datasets
33 var JSON = function () {
45 var a = ['['], b, f, i, l = x.length, v;
46 for (i = 0; i < l; i += 1) {
51 if (typeof v == 'string') {
63 'boolean': function (x) {
66 'null': function (x) {
69 number: function (x) {
70 return isFinite(x) ? String(x) : 'null';
72 object: function (x) {
74 if (x instanceof Array) {
77 var a = ['{'], b, f, i, v;
79 if (!x.hasOwnProperty || x.hasOwnProperty(i)) {
84 if (typeof v == 'string') {
88 a.push(s.string(i), ':', v);
99 string: function (x) {
101 var unicode = new String;
102 for(var i=0; i<x.length; i++) {
103 var temp = x.charCodeAt(i).toString(16) ;
104 while(temp.length < 4) {
107 unicode += '\\u' + temp;
109 return '"' + unicode + '"';
114 Stringify a JavaScript value, adding a security envelope, producing a JSON text.
116 stringify: function (v) {
120 if (typeof v === 'string') {
121 // cn: bug 12274 - add a security envelope to protect against CSRF
122 var securityEnvelope = "{asynchronous_key:'" + asynchronous_key +"', jsonObject:" + v + "}";
123 return securityEnvelope;
129 destringify: function(str) {
133 Stringify a JavaScript value, NO security envelope, producing a JSON text.
135 stringifyNoSecurity : function (v) {
139 if (typeof v === 'string') {
146 destringify: function(str) {
151 Parse a JSON text, producing a JavaScript value.
152 It returns false if there is a syntax error.
154 parse: function (text) {
156 text = text.replace(/^\s*|\s*$/,'');
157 // cn: bug 12274 - the below defend against CSRF (see desc for whitepaper)
159 if(text.substr(0,11) == "while(1);/*") {
160 text = text.substr(11);
161 text = text.substr(0, (text.length - 2));
166 // In the second stage, we run the text against regular expressions that look
167 // for non-JSON patterns. We are especially concerned with '()' and 'new'
168 // because they can cause invocation, and '=' because it can cause mutation.
169 // But just to be safe, we want to reject all unexpected forms.
171 // We split the second stage into 4 regexp operations in order to work around
172 // crippling inefficiencies in IE's and Safari's regexp engines. First we
173 // replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
174 // replace all simple value tokens with ']' characters. Third, we delete all
175 // open brackets that follow a colon or comma or that begin the text. Finally,
176 // we look to see that the remaining characters are only whitespace or ']' or
177 // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
179 if (/^[\],:{}\s]*$/.test(text
180 .replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
181 .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
182 .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
184 // In the third stage we use the eval function to compile the text into a
185 // JavaScript structure. The '{' operator is subject to a syntactic ambiguity
186 // in JavaScript: it can begin a block or an object literal. We wrap the text
187 // in parens to eliminate the ambiguity.
188 return eval('(' + text + ')');
198 * SUGAR: in response to CSRF, keep a standard copy of the parse function
200 parseNoSecurity: function (text) {
202 // See the comments in the above function for a description of what this mess is
203 if (/^[\],:{}\s]*$/.test(text
204 .replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
205 .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
206 .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
208 return eval('(' + text + ')');