mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
346 lines
12 KiB
JavaScript
346 lines
12 KiB
JavaScript
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* ***** BEGIN LICENSE BLOCK *****
|
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
|
*
|
|
* The contents of this file are subject to the Mozilla Public License Version
|
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
* http://www.mozilla.org/MPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
* for the specific language governing rights and limitations under the
|
|
* License.
|
|
*
|
|
* The Original Code is JavaScript Engine testing utilities.
|
|
*
|
|
* The Initial Developer of the Original Code is
|
|
* Mozilla Foundation.
|
|
* Portions created by the Initial Developer are Copyright (C) 2008
|
|
* the Initial Developer. All Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
*
|
|
* Alternatively, the contents of this file may be used under the terms of
|
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
|
* of those above. If you wish to allow use of your version of this file only
|
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
|
* use your version of this file under the terms of the MPL, indicate your
|
|
* decision by deleting the provisions above and replace them with the notice
|
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
|
* the provisions above, a recipient may use your version of this file under
|
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
|
*
|
|
* ***** END LICENSE BLOCK ***** */
|
|
|
|
var gTestfile = 'regress-450369.js';
|
|
//-----------------------------------------------------------------------------
|
|
var BUGNUMBER = 450369;
|
|
var summary = 'Crash with JIT and json2.js';
|
|
var actual = 'No Crash';
|
|
var expect = 'No Crash';
|
|
|
|
jit(true);
|
|
|
|
/*
|
|
json2.js
|
|
2007-11-06
|
|
|
|
Public Domain
|
|
|
|
See http://www.JSON.org/js.html
|
|
|
|
This file creates a global JSON object containing two methods:
|
|
|
|
JSON.stringify(value, whitelist)
|
|
value any JavaScript value, usually an object or array.
|
|
|
|
whitelist an optional that determines how object values are
|
|
stringified.
|
|
|
|
This method produces a JSON text from a JavaScript value.
|
|
There are three possible ways to stringify an object, depending
|
|
on the optional whitelist parameter.
|
|
|
|
If an object has a toJSON method, then the toJSON() method will be
|
|
called. The value returned from the toJSON method will be
|
|
stringified.
|
|
|
|
Otherwise, if the optional whitelist parameter is an array, then
|
|
the elements of the array will be used to select members of the
|
|
object for stringification.
|
|
|
|
Otherwise, if there is no whitelist parameter, then all of the
|
|
members of the object will be stringified.
|
|
|
|
Values that do not have JSON representaions, such as undefined or
|
|
functions, will not be serialized. Such values in objects will be
|
|
dropped, in arrays will be replaced with null. JSON.stringify()
|
|
returns undefined. Dates will be stringified as quoted ISO dates.
|
|
|
|
Example:
|
|
|
|
var text = JSON.stringify(['e', {pluribus: 'unum'}]);
|
|
// text is '["e",{"pluribus":"unum"}]'
|
|
|
|
JSON.parse(text, filter)
|
|
This method parses a JSON text to produce an object or
|
|
array. It can throw a SyntaxError exception.
|
|
|
|
The optional filter parameter is a function that can filter and
|
|
transform the results. It receives each of the keys and values, and
|
|
its return value is used instead of the original value. If it
|
|
returns what it received, then structure is not modified. If it
|
|
returns undefined then the member is deleted.
|
|
|
|
Example:
|
|
|
|
// Parse the text. If a key contains the string 'date' then
|
|
// convert the value to a date.
|
|
|
|
myData = JSON.parse(text, function (key, value) {
|
|
return key.indexOf('date') >= 0 ? new Date(value) : value;
|
|
});
|
|
|
|
This is a reference implementation. You are free to copy, modify, or
|
|
redistribute.
|
|
|
|
Use your own copy. It is extremely unwise to load third party
|
|
code into your pages.
|
|
*/
|
|
|
|
/*jslint evil: true */
|
|
/*extern JSON */
|
|
|
|
if (!this.emulatedJSON) {
|
|
|
|
emulatedJSON = function () {
|
|
|
|
function f(n) { // Format integers to have at least two digits.
|
|
return n < 10 ? '0' + n : n;
|
|
}
|
|
|
|
Date.prototype.toJSON = function () {
|
|
|
|
// Eventually, this method will be based on the date.toISOString method.
|
|
|
|
return this.getUTCFullYear() + '-' +
|
|
f(this.getUTCMonth() + 1) + '-' +
|
|
f(this.getUTCDate()) + 'T' +
|
|
f(this.getUTCHours()) + ':' +
|
|
f(this.getUTCMinutes()) + ':' +
|
|
f(this.getUTCSeconds()) + 'Z';
|
|
};
|
|
|
|
|
|
var m = { // table of character substitutions
|
|
'\b': '\\b',
|
|
'\t': '\\t',
|
|
'\n': '\\n',
|
|
'\f': '\\f',
|
|
'\r': '\\r',
|
|
'"' : '\\"',
|
|
'\\': '\\\\'
|
|
};
|
|
|
|
function stringify(value, whitelist) {
|
|
var a, // The array holding the partial texts.
|
|
i, // The loop counter.
|
|
k, // The member key.
|
|
l, // Length.
|
|
r = /["\\\x00-\x1f\x7f-\x9f]/g,
|
|
v; // The member value.
|
|
|
|
switch (typeof value) {
|
|
case 'string':
|
|
|
|
// If the string contains no control characters, no quote characters, and no
|
|
// backslash characters, then we can safely slap some quotes around it.
|
|
// Otherwise we must also replace the offending characters with safe sequences.
|
|
|
|
return r.test(value) ?
|
|
'"' + value.replace(r, function (a) {
|
|
var c = m[a];
|
|
if (c) {
|
|
return c;
|
|
}
|
|
c = a.charCodeAt();
|
|
return '\\u00' + Math.floor(c / 16).toString(16) +
|
|
(c % 16).toString(16);
|
|
}) + '"' :
|
|
'"' + value + '"';
|
|
|
|
case 'number':
|
|
|
|
// JSON numbers must be finite. Encode non-finite numbers as null.
|
|
|
|
return isFinite(value) ? String(value) : 'null';
|
|
|
|
case 'boolean':
|
|
case 'null':
|
|
return String(value);
|
|
|
|
case 'object':
|
|
|
|
// Due to a specification blunder in ECMAScript,
|
|
// typeof null is 'object', so watch out for that case.
|
|
|
|
if (!value) {
|
|
return 'null';
|
|
}
|
|
|
|
// If the object has a toJSON method, call it, and stringify the result.
|
|
|
|
if (typeof value.toJSON === 'function') {
|
|
return stringify(value.toJSON());
|
|
}
|
|
a = [];
|
|
if (typeof value.length === 'number' &&
|
|
!(value.propertyIsEnumerable('length'))) {
|
|
|
|
// The object is an array. Stringify every element. Use null as a placeholder
|
|
// for non-JSON values.
|
|
|
|
l = value.length;
|
|
for (i = 0; i < l; i += 1) {
|
|
a.push(stringify(value[i], whitelist) || 'null');
|
|
}
|
|
|
|
// Join all of the elements together and wrap them in brackets.
|
|
|
|
return '[' + a.join(',') + ']';
|
|
}
|
|
if (whitelist) {
|
|
|
|
// If a whitelist (array of keys) is provided, use it to select the components
|
|
// of the object.
|
|
|
|
l = whitelist.length;
|
|
for (i = 0; i < l; i += 1) {
|
|
k = whitelist[i];
|
|
if (typeof k === 'string') {
|
|
v = stringify(value[k], whitelist);
|
|
if (v) {
|
|
a.push(stringify(k) + ':' + v);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
|
|
// Otherwise, iterate through all of the keys in the object.
|
|
|
|
for (k in value) {
|
|
if (typeof k === 'string') {
|
|
v = stringify(value[k], whitelist);
|
|
if (v) {
|
|
a.push(stringify(k) + ':' + v);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Join all of the member texts together and wrap them in braces.
|
|
|
|
return '{' + a.join(',') + '}';
|
|
}
|
|
return undefined;
|
|
}
|
|
|
|
return {
|
|
stringify: stringify,
|
|
parse: function (text, filter) {
|
|
var j;
|
|
|
|
function walk(k, v) {
|
|
var i, n;
|
|
if (v && typeof v === 'object') {
|
|
for (i in v) {
|
|
if (Object.prototype.hasOwnProperty.apply(v, [i])) {
|
|
n = walk(i, v[i]);
|
|
if (n !== undefined) {
|
|
v[i] = n;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return filter(k, v);
|
|
}
|
|
|
|
|
|
// Parsing happens in three stages. In the first stage, we run the text against
|
|
// regular expressions that look for non-JSON patterns. We are especially
|
|
// concerned with '()' and 'new' because they can cause invocation, and '='
|
|
// because it can cause mutation. But just to be safe, we want to reject all
|
|
// unexpected forms.
|
|
|
|
// We split the first stage into 4 regexp operations in order to work around
|
|
// crippling inefficiencies in IE's and Safari's regexp engines. First we
|
|
// replace all backslash pairs with '@' (a non-JSON character). Second, we
|
|
// replace all simple value tokens with ']' characters. Third, we delete all
|
|
// open brackets that follow a colon or comma or that begin the text. Finally,
|
|
// we look to see that the remaining characters are only whitespace or ']' or
|
|
// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
|
|
|
|
if (/^[\],:{}\s]*$/.test(text.replace(/\\./g, '@').
|
|
replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(:?[eE][+\-]?\d+)?/g, ']').
|
|
replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
|
|
|
|
// In the second stage we use the eval function to compile the text into a
|
|
// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
|
|
// in JavaScript: it can begin a block or an object literal. We wrap the text
|
|
// in parens to eliminate the ambiguity.
|
|
|
|
j = eval('(' + text + ')');
|
|
|
|
// In the optional third stage, we recursively walk the new structure, passing
|
|
// each name/value pair to a filter function for possible transformation.
|
|
|
|
return typeof filter === 'function' ? walk('', j) : j;
|
|
}
|
|
|
|
// If the text is not JSON parseable, then a SyntaxError is thrown.
|
|
|
|
throw new SyntaxError('parseJSON');
|
|
}
|
|
};
|
|
}();
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
test();
|
|
//-----------------------------------------------------------------------------
|
|
|
|
jit(false);
|
|
|
|
function test()
|
|
{
|
|
enterFunc ('test');
|
|
printBugNumber(BUGNUMBER);
|
|
printStatus (summary);
|
|
|
|
|
|
var testPairs = [
|
|
["{}", {}],
|
|
["[]", []],
|
|
['{"foo":"bar"}', {"foo":"bar"}],
|
|
['{"null":null}', {"null":null}],
|
|
['{"five":5}', {"five":5}],
|
|
]
|
|
|
|
var a = [];
|
|
for (var i=0; i < testPairs.length; i++) {
|
|
var pair = testPairs[i];
|
|
var s = emulatedJSON.stringify(pair[1])
|
|
a[i] = s;
|
|
}
|
|
print(a.join("\n"));
|
|
|
|
reportCompare(expect, actual, summary);
|
|
|
|
exitFunc ('test');
|
|
}
|
|
|