regress-450369.js (10571B)
1 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 //----------------------------------------------------------------------------- 7 var BUGNUMBER = 450369; 8 var summary = 'Crash with JIT and json2.js'; 9 var actual = 'No Crash'; 10 var expect = 'No Crash'; 11 12 13 /* 14 json2.js 15 2007-11-06 16 17 Public Domain 18 19 See http://www.JSON.org/js.html 20 21 This file creates a global JSON object containing two methods: 22 23 JSON.stringify(value, whitelist) 24 value any JavaScript value, usually an object or array. 25 26 whitelist an optional that determines how object values are 27 stringified. 28 29 This method produces a JSON text from a JavaScript value. 30 There are three possible ways to stringify an object, depending 31 on the optional whitelist parameter. 32 33 If an object has a toJSON method, then the toJSON() method will be 34 called. The value returned from the toJSON method will be 35 stringified. 36 37 Otherwise, if the optional whitelist parameter is an array, then 38 the elements of the array will be used to select members of the 39 object for stringification. 40 41 Otherwise, if there is no whitelist parameter, then all of the 42 members of the object will be stringified. 43 44 Values that do not have JSON representaions, such as undefined or 45 functions, will not be serialized. Such values in objects will be 46 dropped, in arrays will be replaced with null. JSON.stringify() 47 returns undefined. Dates will be stringified as quoted ISO dates. 48 49 Example: 50 51 var text = JSON.stringify(['e', {pluribus: 'unum'}]); 52 // text is '["e",{"pluribus":"unum"}]' 53 54 JSON.parse(text, filter) 55 This method parses a JSON text to produce an object or 56 array. It can throw a SyntaxError exception. 57 58 The optional filter parameter is a function that can filter and 59 transform the results. It receives each of the keys and values, and 60 its return value is used instead of the original value. If it 61 returns what it received, then structure is not modified. If it 62 returns undefined then the member is deleted. 63 64 Example: 65 66 // Parse the text. If a key contains the string 'date' then 67 // convert the value to a date. 68 69 myData = JSON.parse(text, function (key, value) { 70 return key.indexOf('date') >= 0 ? new Date(value) : value; 71 }); 72 73 This is a reference implementation. You are free to copy, modify, or 74 redistribute. 75 76 Use your own copy. It is extremely unwise to load third party 77 code into your pages. 78 */ 79 80 /*jslint evil: true */ 81 /*extern JSON */ 82 83 if (!this.emulatedJSON) { 84 85 emulatedJSON = function () { 86 87 function f(n) { // Format integers to have at least two digits. 88 return n < 10 ? '0' + n : n; 89 } 90 91 Date.prototype.toJSON = function () { 92 93 // Eventually, this method will be based on the date.toISOString method. 94 95 return this.getUTCFullYear() + '-' + 96 f(this.getUTCMonth() + 1) + '-' + 97 f(this.getUTCDate()) + 'T' + 98 f(this.getUTCHours()) + ':' + 99 f(this.getUTCMinutes()) + ':' + 100 f(this.getUTCSeconds()) + 'Z'; 101 }; 102 103 104 var m = { // table of character substitutions 105 '\b': '\\b', 106 '\t': '\\t', 107 '\n': '\\n', 108 '\f': '\\f', 109 '\r': '\\r', 110 '"' : '\\"', 111 '\\': '\\\\' 112 }; 113 114 function stringify(value, whitelist) { 115 var a, // The array holding the partial texts. 116 i, // The loop counter. 117 k, // The member key. 118 l, // Length. 119 r = /["\\\x00-\x1f\x7f-\x9f]/g, 120 v; // The member value. 121 122 switch (typeof value) { 123 case 'string': 124 125 // If the string contains no control characters, no quote characters, and no 126 // backslash characters, then we can safely slap some quotes around it. 127 // Otherwise we must also replace the offending characters with safe sequences. 128 129 return r.test(value) ? 130 '"' + value.replace(r, function (a) { 131 var c = m[a]; 132 if (c) { 133 return c; 134 } 135 c = a.charCodeAt(); 136 return '\\u00' + Math.floor(c / 16).toString(16) + 137 (c % 16).toString(16); 138 }) + '"' : 139 '"' + value + '"'; 140 141 case 'number': 142 143 // JSON numbers must be finite. Encode non-finite numbers as null. 144 145 return isFinite(value) ? String(value) : 'null'; 146 147 case 'boolean': 148 case 'null': 149 return String(value); 150 151 case 'object': 152 153 // Due to a specification blunder in ECMAScript, 154 // typeof null is 'object', so watch out for that case. 155 156 if (!value) { 157 return 'null'; 158 } 159 160 // If the object has a toJSON method, call it, and stringify the result. 161 162 if (typeof value.toJSON === 'function') { 163 return stringify(value.toJSON()); 164 } 165 a = []; 166 if (typeof value.length === 'number' && 167 !(value.propertyIsEnumerable('length'))) { 168 169 // The object is an array. Stringify every element. Use null as a placeholder 170 // for non-JSON values. 171 172 l = value.length; 173 for (i = 0; i < l; i += 1) { 174 a.push(stringify(value[i], whitelist) || 'null'); 175 } 176 177 // Join all of the elements together and wrap them in brackets. 178 179 return '[' + a.join(',') + ']'; 180 } 181 if (whitelist) { 182 183 // If a whitelist (array of keys) is provided, use it to select the components 184 // of the object. 185 186 l = whitelist.length; 187 for (i = 0; i < l; i += 1) { 188 k = whitelist[i]; 189 if (typeof k === 'string') { 190 v = stringify(value[k], whitelist); 191 if (v) { 192 a.push(stringify(k) + ':' + v); 193 } 194 } 195 } 196 } else { 197 198 // Otherwise, iterate through all of the keys in the object. 199 200 for (k in value) { 201 if (typeof k === 'string') { 202 v = stringify(value[k], whitelist); 203 if (v) { 204 a.push(stringify(k) + ':' + v); 205 } 206 } 207 } 208 } 209 210 // Join all of the member texts together and wrap them in braces. 211 212 return '{' + a.join(',') + '}'; 213 } 214 return undefined; 215 } 216 217 return { 218 stringify: stringify, 219 parse: function (text, filter) { 220 var j; 221 222 function walk(k, v) { 223 var i, n; 224 if (v && typeof v === 'object') { 225 for (i in v) { 226 if (Object.prototype.hasOwnProperty.apply(v, [i])) { 227 n = walk(i, v[i]); 228 if (n !== undefined) { 229 v[i] = n; 230 } 231 } 232 } 233 } 234 return filter(k, v); 235 } 236 237 238 // Parsing happens in three stages. In the first stage, we run the text against 239 // regular expressions that look for non-JSON patterns. We are especially 240 // concerned with '()' and 'new' because they can cause invocation, and '=' 241 // because it can cause mutation. But just to be safe, we want to reject all 242 // unexpected forms. 243 244 // We split the first stage into 4 regexp operations in order to work around 245 // crippling inefficiencies in IE's and Safari's regexp engines. First we 246 // replace all backslash pairs with '@' (a non-JSON character). Second, we 247 // replace all simple value tokens with ']' characters. Third, we delete all 248 // open brackets that follow a colon or comma or that begin the text. Finally, 249 // we look to see that the remaining characters are only whitespace or ']' or 250 // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. 251 252 if (/^[\],:{}\s]*$/.test(text.replace(/\\./g, '@'). 253 replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(:?[eE][+\-]?\d+)?/g, ']'). 254 replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { 255 256 // In the second stage we use the eval function to compile the text into a 257 // JavaScript structure. The '{' operator is subject to a syntactic ambiguity 258 // in JavaScript: it can begin a block or an object literal. We wrap the text 259 // in parens to eliminate the ambiguity. 260 261 j = eval('(' + text + ')'); 262 263 // In the optional third stage, we recursively walk the new structure, passing 264 // each name/value pair to a filter function for possible transformation. 265 266 return typeof filter === 'function' ? walk('', j) : j; 267 } 268 269 // If the text is not JSON parseable, then a SyntaxError is thrown. 270 271 throw new SyntaxError('parseJSON'); 272 } 273 }; 274 }(); 275 } 276 277 278 //----------------------------------------------------------------------------- 279 test(); 280 //----------------------------------------------------------------------------- 281 282 283 function test() 284 { 285 printBugNumber(BUGNUMBER); 286 printStatus (summary); 287 288 289 var testPairs = [ 290 ["{}", {}], 291 ["[]", []], 292 ['{"foo":"bar"}', {"foo":"bar"}], 293 ['{"null":null}', {"null":null}], 294 ['{"five":5}', {"five":5}], 295 ] 296 297 var a = []; 298 for (var i=0; i < testPairs.length; i++) { 299 var pair = testPairs[i]; 300 var s = emulatedJSON.stringify(pair[1]) 301 a[i] = s; 302 } 303 print(a.join("\n")); 304 305 reportCompare(expect, actual, summary); 306 }