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