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

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

mercurial