1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/js/src/tests/js1_5/Regress/regress-450369.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,312 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +//----------------------------------------------------------------------------- 1.10 +var BUGNUMBER = 450369; 1.11 +var summary = 'Crash with JIT and json2.js'; 1.12 +var actual = 'No Crash'; 1.13 +var expect = 'No Crash'; 1.14 + 1.15 +jit(true); 1.16 + 1.17 +/* 1.18 + json2.js 1.19 + 2007-11-06 1.20 + 1.21 + Public Domain 1.22 + 1.23 + See http://www.JSON.org/js.html 1.24 + 1.25 + This file creates a global JSON object containing two methods: 1.26 + 1.27 + JSON.stringify(value, whitelist) 1.28 + value any JavaScript value, usually an object or array. 1.29 + 1.30 + whitelist an optional that determines how object values are 1.31 + stringified. 1.32 + 1.33 + This method produces a JSON text from a JavaScript value. 1.34 + There are three possible ways to stringify an object, depending 1.35 + on the optional whitelist parameter. 1.36 + 1.37 + If an object has a toJSON method, then the toJSON() method will be 1.38 + called. The value returned from the toJSON method will be 1.39 + stringified. 1.40 + 1.41 + Otherwise, if the optional whitelist parameter is an array, then 1.42 + the elements of the array will be used to select members of the 1.43 + object for stringification. 1.44 + 1.45 + Otherwise, if there is no whitelist parameter, then all of the 1.46 + members of the object will be stringified. 1.47 + 1.48 + Values that do not have JSON representaions, such as undefined or 1.49 + functions, will not be serialized. Such values in objects will be 1.50 + dropped, in arrays will be replaced with null. JSON.stringify() 1.51 + returns undefined. Dates will be stringified as quoted ISO dates. 1.52 + 1.53 + Example: 1.54 + 1.55 + var text = JSON.stringify(['e', {pluribus: 'unum'}]); 1.56 + // text is '["e",{"pluribus":"unum"}]' 1.57 + 1.58 + JSON.parse(text, filter) 1.59 + This method parses a JSON text to produce an object or 1.60 + array. It can throw a SyntaxError exception. 1.61 + 1.62 + The optional filter parameter is a function that can filter and 1.63 + transform the results. It receives each of the keys and values, and 1.64 + its return value is used instead of the original value. If it 1.65 + returns what it received, then structure is not modified. If it 1.66 + returns undefined then the member is deleted. 1.67 + 1.68 + Example: 1.69 + 1.70 + // Parse the text. If a key contains the string 'date' then 1.71 + // convert the value to a date. 1.72 + 1.73 + myData = JSON.parse(text, function (key, value) { 1.74 + return key.indexOf('date') >= 0 ? new Date(value) : value; 1.75 + }); 1.76 + 1.77 + This is a reference implementation. You are free to copy, modify, or 1.78 + redistribute. 1.79 + 1.80 + Use your own copy. It is extremely unwise to load third party 1.81 + code into your pages. 1.82 +*/ 1.83 + 1.84 +/*jslint evil: true */ 1.85 +/*extern JSON */ 1.86 + 1.87 +if (!this.emulatedJSON) { 1.88 + 1.89 + emulatedJSON = function () { 1.90 + 1.91 + function f(n) { // Format integers to have at least two digits. 1.92 + return n < 10 ? '0' + n : n; 1.93 + } 1.94 + 1.95 + Date.prototype.toJSON = function () { 1.96 + 1.97 +// Eventually, this method will be based on the date.toISOString method. 1.98 + 1.99 + return this.getUTCFullYear() + '-' + 1.100 + f(this.getUTCMonth() + 1) + '-' + 1.101 + f(this.getUTCDate()) + 'T' + 1.102 + f(this.getUTCHours()) + ':' + 1.103 + f(this.getUTCMinutes()) + ':' + 1.104 + f(this.getUTCSeconds()) + 'Z'; 1.105 + }; 1.106 + 1.107 + 1.108 + var m = { // table of character substitutions 1.109 + '\b': '\\b', 1.110 + '\t': '\\t', 1.111 + '\n': '\\n', 1.112 + '\f': '\\f', 1.113 + '\r': '\\r', 1.114 + '"' : '\\"', 1.115 + '\\': '\\\\' 1.116 + }; 1.117 + 1.118 + function stringify(value, whitelist) { 1.119 + var a, // The array holding the partial texts. 1.120 + i, // The loop counter. 1.121 + k, // The member key. 1.122 + l, // Length. 1.123 + r = /["\\\x00-\x1f\x7f-\x9f]/g, 1.124 + v; // The member value. 1.125 + 1.126 + switch (typeof value) { 1.127 + case 'string': 1.128 + 1.129 +// If the string contains no control characters, no quote characters, and no 1.130 +// backslash characters, then we can safely slap some quotes around it. 1.131 +// Otherwise we must also replace the offending characters with safe sequences. 1.132 + 1.133 + return r.test(value) ? 1.134 + '"' + value.replace(r, function (a) { 1.135 + var c = m[a]; 1.136 + if (c) { 1.137 + return c; 1.138 + } 1.139 + c = a.charCodeAt(); 1.140 + return '\\u00' + Math.floor(c / 16).toString(16) + 1.141 + (c % 16).toString(16); 1.142 + }) + '"' : 1.143 + '"' + value + '"'; 1.144 + 1.145 + case 'number': 1.146 + 1.147 +// JSON numbers must be finite. Encode non-finite numbers as null. 1.148 + 1.149 + return isFinite(value) ? String(value) : 'null'; 1.150 + 1.151 + case 'boolean': 1.152 + case 'null': 1.153 + return String(value); 1.154 + 1.155 + case 'object': 1.156 + 1.157 +// Due to a specification blunder in ECMAScript, 1.158 +// typeof null is 'object', so watch out for that case. 1.159 + 1.160 + if (!value) { 1.161 + return 'null'; 1.162 + } 1.163 + 1.164 +// If the object has a toJSON method, call it, and stringify the result. 1.165 + 1.166 + if (typeof value.toJSON === 'function') { 1.167 + return stringify(value.toJSON()); 1.168 + } 1.169 + a = []; 1.170 + if (typeof value.length === 'number' && 1.171 + !(value.propertyIsEnumerable('length'))) { 1.172 + 1.173 +// The object is an array. Stringify every element. Use null as a placeholder 1.174 +// for non-JSON values. 1.175 + 1.176 + l = value.length; 1.177 + for (i = 0; i < l; i += 1) { 1.178 + a.push(stringify(value[i], whitelist) || 'null'); 1.179 + } 1.180 + 1.181 +// Join all of the elements together and wrap them in brackets. 1.182 + 1.183 + return '[' + a.join(',') + ']'; 1.184 + } 1.185 + if (whitelist) { 1.186 + 1.187 +// If a whitelist (array of keys) is provided, use it to select the components 1.188 +// of the object. 1.189 + 1.190 + l = whitelist.length; 1.191 + for (i = 0; i < l; i += 1) { 1.192 + k = whitelist[i]; 1.193 + if (typeof k === 'string') { 1.194 + v = stringify(value[k], whitelist); 1.195 + if (v) { 1.196 + a.push(stringify(k) + ':' + v); 1.197 + } 1.198 + } 1.199 + } 1.200 + } else { 1.201 + 1.202 +// Otherwise, iterate through all of the keys in the object. 1.203 + 1.204 + for (k in value) { 1.205 + if (typeof k === 'string') { 1.206 + v = stringify(value[k], whitelist); 1.207 + if (v) { 1.208 + a.push(stringify(k) + ':' + v); 1.209 + } 1.210 + } 1.211 + } 1.212 + } 1.213 + 1.214 +// Join all of the member texts together and wrap them in braces. 1.215 + 1.216 + return '{' + a.join(',') + '}'; 1.217 + } 1.218 + return undefined; 1.219 + } 1.220 + 1.221 + return { 1.222 + stringify: stringify, 1.223 + parse: function (text, filter) { 1.224 + var j; 1.225 + 1.226 + function walk(k, v) { 1.227 + var i, n; 1.228 + if (v && typeof v === 'object') { 1.229 + for (i in v) { 1.230 + if (Object.prototype.hasOwnProperty.apply(v, [i])) { 1.231 + n = walk(i, v[i]); 1.232 + if (n !== undefined) { 1.233 + v[i] = n; 1.234 + } 1.235 + } 1.236 + } 1.237 + } 1.238 + return filter(k, v); 1.239 + } 1.240 + 1.241 + 1.242 +// Parsing happens in three stages. In the first stage, we run the text against 1.243 +// regular expressions that look for non-JSON patterns. We are especially 1.244 +// concerned with '()' and 'new' because they can cause invocation, and '=' 1.245 +// because it can cause mutation. But just to be safe, we want to reject all 1.246 +// unexpected forms. 1.247 + 1.248 +// We split the first stage into 4 regexp operations in order to work around 1.249 +// crippling inefficiencies in IE's and Safari's regexp engines. First we 1.250 +// replace all backslash pairs with '@' (a non-JSON character). Second, we 1.251 +// replace all simple value tokens with ']' characters. Third, we delete all 1.252 +// open brackets that follow a colon or comma or that begin the text. Finally, 1.253 +// we look to see that the remaining characters are only whitespace or ']' or 1.254 +// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. 1.255 + 1.256 + if (/^[\],:{}\s]*$/.test(text.replace(/\\./g, '@'). 1.257 +replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(:?[eE][+\-]?\d+)?/g, ']'). 1.258 +replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { 1.259 + 1.260 +// In the second stage we use the eval function to compile the text into a 1.261 +// JavaScript structure. The '{' operator is subject to a syntactic ambiguity 1.262 +// in JavaScript: it can begin a block or an object literal. We wrap the text 1.263 +// in parens to eliminate the ambiguity. 1.264 + 1.265 + j = eval('(' + text + ')'); 1.266 + 1.267 +// In the optional third stage, we recursively walk the new structure, passing 1.268 +// each name/value pair to a filter function for possible transformation. 1.269 + 1.270 + return typeof filter === 'function' ? walk('', j) : j; 1.271 + } 1.272 + 1.273 +// If the text is not JSON parseable, then a SyntaxError is thrown. 1.274 + 1.275 + throw new SyntaxError('parseJSON'); 1.276 + } 1.277 + }; 1.278 + }(); 1.279 +} 1.280 + 1.281 + 1.282 +//----------------------------------------------------------------------------- 1.283 +test(); 1.284 +//----------------------------------------------------------------------------- 1.285 + 1.286 +jit(false); 1.287 + 1.288 +function test() 1.289 +{ 1.290 + enterFunc ('test'); 1.291 + printBugNumber(BUGNUMBER); 1.292 + printStatus (summary); 1.293 + 1.294 + 1.295 + var testPairs = [ 1.296 + ["{}", {}], 1.297 + ["[]", []], 1.298 + ['{"foo":"bar"}', {"foo":"bar"}], 1.299 + ['{"null":null}', {"null":null}], 1.300 + ['{"five":5}', {"five":5}], 1.301 + ] 1.302 + 1.303 + var a = []; 1.304 + for (var i=0; i < testPairs.length; i++) { 1.305 + var pair = testPairs[i]; 1.306 + var s = emulatedJSON.stringify(pair[1]) 1.307 + a[i] = s; 1.308 + } 1.309 + print(a.join("\n")); 1.310 + 1.311 + reportCompare(expect, actual, summary); 1.312 + 1.313 + exitFunc ('test'); 1.314 +} 1.315 +