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

changeset 0
6474c204b198
     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 +

mercurial