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
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/
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
15 * The Original Code is JavaScript Engine testing utilities.
17 * The Initial Developer of the Original Code is
19 * Portions created by the Initial Developer are Copyright (C) 2008
20 * the Initial Developer. All Rights Reserved.
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.
36 * ***** END LICENSE BLOCK ***** */
38 //-----------------------------------------------------------------------------
39 var BUGNUMBER = 450369;
40 var summary = 'Crash with JIT and json2.js';
41 var actual = 'No Crash';
42 var expect = 'No Crash';
52 See http://www.JSON.org/js.html
54 This file creates a global JSON object containing two methods:
56 JSON.stringify(value, whitelist)
57 value any JavaScript value, usually an object or array.
59 whitelist an optional that determines how object values are
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.
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
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.
74 Otherwise, if there is no whitelist parameter, then all of the
75 members of the object will be stringified.
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.
84 var text = JSON.stringify(['e', {pluribus: 'unum'}]);
85 // text is '["e",{"pluribus":"unum"}]'
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.
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.
99 // Parse the text. If a key contains the string 'date' then
100 // convert the value to a date.
102 myData = JSON.parse(text, function (key, value) {
103 return key.indexOf('date') >= 0 ? new Date(value) : value;
106 This is a reference implementation. You are free to copy, modify, or
109 Use your own copy. It is extremely unwise to load third party
110 code into your pages.
113 /*jslint evil: true */
116 if (!this.emulatedJSON) {
118 emulatedJSON = function () {
120 function f(n) { // Format integers to have at least two digits.
121 return n < 10 ? '0' + n : n;
124 Date.prototype.toJSON = function () {
126 // Eventually, this method will be based on the date.toISOString method.
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';
137 var m = { // table of character substitutions
147 function stringify(value, whitelist) {
148 var a, // The array holding the partial texts.
149 i, // The loop counter.
150 k, // The member key.
152 r = /["\\\x00-\x1f\x7f-\x9f]/g,
153 v; // The member value.
155 switch (typeof value) {
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.
162 return r.test(value) ?
163 '"' + value.replace(r, function (a) {
169 return '\\u00' + Math.floor(c / 16).toString(16) +
170 (c % 16).toString(16);
176 // JSON numbers must be finite. Encode non-finite numbers as null.
178 return isFinite(value) ? String(value) : 'null';
182 return String(value);
186 // Due to a specification blunder in ECMAScript,
187 // typeof null is 'object', so watch out for that case.
193 // If the object has a toJSON method, call it, and stringify the result.
195 if (typeof value.toJSON === 'function') {
196 return stringify(value.toJSON());
199 if (typeof value.length === 'number' &&
200 !(value.propertyIsEnumerable('length'))) {
202 // The object is an array. Stringify every element. Use null as a placeholder
203 // for non-JSON values.
206 for (i = 0; i < l; i += 1) {
207 a.push(stringify(value[i], whitelist) || 'null');
210 // Join all of the elements together and wrap them in brackets.
212 return '[' + a.join(',') + ']';
216 // If a whitelist (array of keys) is provided, use it to select the components
219 l = whitelist.length;
220 for (i = 0; i < l; i += 1) {
222 if (typeof k === 'string') {
223 v = stringify(value[k], whitelist);
225 a.push(stringify(k) + ':' + v);
231 // Otherwise, iterate through all of the keys in the object.
234 if (typeof k === 'string') {
235 v = stringify(value[k], whitelist);
237 a.push(stringify(k) + ':' + v);
243 // Join all of the member texts together and wrap them in braces.
245 return '{' + a.join(',') + '}';
251 stringify: stringify,
252 parse: function (text, filter) {
255 function walk(k, v) {
257 if (v && typeof v === 'object') {
259 if (Object.prototype.hasOwnProperty.apply(v, [i])) {
261 if (n !== undefined) {
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
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.
285 if (/^[\],:{}\s]*$/.test(text.replace(/\\./g, '@').
286 replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(:?[eE][+\-]?\d+)?/g, ']').
287 replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
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.
294 j = eval('(' + text + ')');
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.
299 return typeof filter === 'function' ? walk('', j) : j;
302 // If the text is not JSON parseable, then a SyntaxError is thrown.
304 throw new SyntaxError('parseJSON');
311 //-----------------------------------------------------------------------------
313 //-----------------------------------------------------------------------------
320 printBugNumber(BUGNUMBER);
321 printStatus (summary);
327 ['{"foo":"bar"}', {"foo":"bar"}],
328 ['{"null":null}', {"null":null}],
329 ['{"five":5}', {"five":5}],
333 for (var i=0; i < testPairs.length; i++) {
334 var pair = testPairs[i];
335 var s = emulatedJSON.stringify(pair[1])
340 reportCompare(expect, actual, summary);