js/src/tests/js1_5/Regress/regress-450369.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial