13a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org// Copyright 2009 the V8 project authors. All rights reserved.
23a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org// Redistribution and use in source and binary forms, with or without
33a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org// modification, are permitted provided that the following conditions are
43a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org// met:
53a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org//
63a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org//     * Redistributions of source code must retain the above copyright
73a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org//       notice, this list of conditions and the following disclaimer.
83a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org//     * Redistributions in binary form must reproduce the above
93a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org//       copyright notice, this list of conditions and the following
103a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org//       disclaimer in the documentation and/or other materials provided
113a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org//       with the distribution.
123a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org//     * Neither the name of Google Inc. nor the names of its
133a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org//       contributors may be used to endorse or promote products derived
143a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org//       from this software without specific prior written permission.
153a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org//
163a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
173a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
183a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
193a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
203a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
213a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
223a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
233a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
243a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
253a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
263a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
273a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org
283a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org// Date toJSON
290c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.orgassertEquals("1970-01-01T00:00:00.000Z", new Date(0).toJSON());
300c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.orgassertEquals("1979-01-11T08:00:00.000Z", new Date("1979-01-11 08:00 GMT").toJSON());
310c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.orgassertEquals("2005-05-05T05:05:05.000Z", new Date("2005-05-05 05:05:05 GMT").toJSON());
323a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgvar n1 = new Date(10000);
333a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgn1.toISOString = function () { return "foo"; };
343a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgassertEquals("foo", n1.toJSON());
353a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgvar n2 = new Date(10001);
363a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgn2.toISOString = null;
373a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgassertThrows(function () { n2.toJSON(); }, TypeError);
383a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgvar n4 = new Date(10003);
393a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgn4.toISOString = function () {
403a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  assertEquals(0, arguments.length);
413a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  assertEquals(this, n4);
423a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  return null;
433a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org};
443a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgassertEquals(null, n4.toJSON());
453a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org
466a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.orgassertTrue(Object.prototype === JSON.__proto__);
473a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgassertEquals("[object JSON]", Object.prototype.toString.call(JSON));
483a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org
495f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org//Test Date.prototype.toJSON as generic function.
505f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgvar d1 = {toJSON: Date.prototype.toJSON,
515f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org         toISOString: function() { return 42; }};
525f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgassertEquals(42, d1.toJSON());
535f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
545f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgvar d2 = {toJSON: Date.prototype.toJSON,
555f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org          valueOf: function() { return Infinity; },
565f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org          toISOString: function() { return 42; }};
575f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgassertEquals(null, d2.toJSON());
585f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
595f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgvar d3 = {toJSON: Date.prototype.toJSON,
605f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org          valueOf: "not callable",
615f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org          toString: function() { return Infinity; },
625f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org          toISOString: function() { return 42; }};
635f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
645f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgassertEquals(null, d3.toJSON());
655f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
665f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgvar d4 = {toJSON: Date.prototype.toJSON,
675f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org          valueOf: "not callable",
685f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org          toString: "not callable either",
695f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org          toISOString: function() { return 42; }};
70c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.orgassertThrows("d4.toJSON()", TypeError);  // ToPrimitive throws.
715f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
725f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgvar d5 = {toJSON: Date.prototype.toJSON,
735f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org          valueOf: "not callable",
745f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org          toString: function() { return "Infinity"; },
755f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org          toISOString: function() { return 42; }};
765f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgassertEquals(42, d5.toJSON());
775f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
785f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgvar d6 = {toJSON: Date.prototype.toJSON,
795f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org          toISOString: function() { return ["not primitive"]; }};
805f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgassertEquals(["not primitive"], d6.toJSON());
815f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
825f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgvar d7 = {toJSON: Date.prototype.toJSON,
835f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org          ISOString: "not callable"};
845f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgassertThrows("d7.toJSON()", TypeError);
855f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
863a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org// DontEnum
875f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgfor (var p in this) {
883a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  assertFalse(p == "JSON");
895f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org}
903a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org
913a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org// Parse
923a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgassertEquals({}, JSON.parse("{}"));
93b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgassertEquals({42:37}, JSON.parse('{"42":37}'));
943a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgassertEquals(null, JSON.parse("null"));
953a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgassertEquals(true, JSON.parse("true"));
963a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgassertEquals(false, JSON.parse("false"));
973a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgassertEquals("foo", JSON.parse('"foo"'));
983a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgassertEquals("f\no", JSON.parse('"f\\no"'));
99b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgassertEquals("\b\f\n\r\t\"\u2028\/\\",
100b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org             JSON.parse('"\\b\\f\\n\\r\\t\\"\\u2028\\/\\\\"'));
101b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgassertEquals([1.1], JSON.parse("[1.1]"));
102b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgassertEquals([1], JSON.parse("[1.0]"));
103b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
104b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgassertEquals(0, JSON.parse("0"));
105b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgassertEquals(1, JSON.parse("1"));
106b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgassertEquals(0.1, JSON.parse("0.1"));
1073a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgassertEquals(1.1, JSON.parse("1.1"));
108b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgassertEquals(1.1, JSON.parse("1.100000"));
109b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgassertEquals(1.111111, JSON.parse("1.111111"));
110b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgassertEquals(-0, JSON.parse("-0"));
111b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgassertEquals(-1, JSON.parse("-1"));
112b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgassertEquals(-0.1, JSON.parse("-0.1"));
113b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgassertEquals(-1.1, JSON.parse("-1.1"));
114b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgassertEquals(-1.1, JSON.parse("-1.100000"));
115b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgassertEquals(-1.111111, JSON.parse("-1.111111"));
116b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgassertEquals(11, JSON.parse("1.1e1"));
117b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgassertEquals(11, JSON.parse("1.1e+1"));
118b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgassertEquals(0.11, JSON.parse("1.1e-1"));
119b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgassertEquals(11, JSON.parse("1.1E1"));
120b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgassertEquals(11, JSON.parse("1.1E+1"));
121b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgassertEquals(0.11, JSON.parse("1.1E-1"));
122b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
1233a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgassertEquals([], JSON.parse("[]"));
1243a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgassertEquals([1], JSON.parse("[1]"));
1253a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgassertEquals([1, "2", true, null], JSON.parse('[1, "2", true, null]'));
1263a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org
127b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgassertEquals("", JSON.parse('""'));
128b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgassertEquals(["", "", -0, ""], JSON.parse('[    ""  ,    ""  ,   -0,    ""]'));
129b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgassertEquals("", JSON.parse('""'));
130b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
131b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
1323a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgfunction GetFilter(name) {
1333a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  function Filter(key, value) {
1343a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org    return (key == name) ? undefined : value;
1353a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  }
1363a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  return Filter;
1373a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org}
1383a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org
1393a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgvar pointJson = '{"x": 1, "y": 2}';
1403a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgassertEquals({'x': 1, 'y': 2}, JSON.parse(pointJson));
1413a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgassertEquals({'x': 1}, JSON.parse(pointJson, GetFilter('y')));
1423a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgassertEquals({'y': 2}, JSON.parse(pointJson, GetFilter('x')));
1433a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgassertEquals([1, 2, 3], JSON.parse("[1, 2, 3]"));
1443a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgassertEquals([1, undefined, 3], JSON.parse("[1, 2, 3]", GetFilter(1)));
1453a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgassertEquals([1, 2, undefined], JSON.parse("[1, 2, 3]", GetFilter(2)));
1463a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org
1473a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgfunction DoubleNumbers(key, value) {
1483a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  return (typeof value == 'number') ? 2 * value : value;
1493a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org}
1503a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org
1513a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgvar deepObject = '{"a": {"b": 1, "c": 2}, "d": {"e": {"f": 3}}}';
1523a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgassertEquals({"a": {"b": 1, "c": 2}, "d": {"e": {"f": 3}}},
1533a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org             JSON.parse(deepObject));
1543a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgassertEquals({"a": {"b": 2, "c": 4}, "d": {"e": {"f": 6}}},
1553a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org             JSON.parse(deepObject, DoubleNumbers));
1563a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org
1573a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgfunction TestInvalid(str) {
1583a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  assertThrows(function () { JSON.parse(str); }, SyntaxError);
1593a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org}
1603a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org
1613a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgTestInvalid('abcdef');
1623a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgTestInvalid('isNaN()');
1633a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgTestInvalid('{"x": [1, 2, deepObject]}');
1643a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgTestInvalid('[1, [2, [deepObject], 3], 4]');
1653a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgTestInvalid('function () { return 0; }');
1663a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org
1673a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgTestInvalid("[1, 2");
1683a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgTestInvalid('{"x": 3');
1693a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org
170b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// JavaScript number literals not valid in JSON.
171b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgTestInvalid('[01]');
172b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgTestInvalid('[.1]');
173b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgTestInvalid('[1.]');
174b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgTestInvalid('[1.e1]');
175b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgTestInvalid('[-.1]');
176b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgTestInvalid('[-1.]');
177b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
178b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// Plain invalid number literals.
179b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgTestInvalid('-');
180b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgTestInvalid('--1');
181b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgTestInvalid('-1e');
182b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgTestInvalid('1e--1]');
183b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgTestInvalid('1e+-1');
184b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgTestInvalid('1e-+1');
185b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgTestInvalid('1e++1');
186b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
187b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// JavaScript string literals not valid in JSON.
188b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgTestInvalid("'single quote'");  // Valid JavaScript
189b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgTestInvalid('"\\a invalid escape"');
190b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgTestInvalid('"\\v invalid escape"');  // Valid JavaScript
191b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgTestInvalid('"\\\' invalid escape"');  // Valid JavaScript
192b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgTestInvalid('"\\x42 invalid escape"');  // Valid JavaScript
193b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgTestInvalid('"\\u202 invalid escape"');
194b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgTestInvalid('"\\012 invalid escape"');
195b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgTestInvalid('"Unterminated string');
196b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgTestInvalid('"Unterminated string\\"');
197b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgTestInvalid('"Unterminated string\\\\\\"');
198b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
1995c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Test bad JSON that would be good JavaScript (ES5).
200b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgTestInvalid("{true:42}");
201b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgTestInvalid("{false:42}");
202b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgTestInvalid("{null:42}");
203b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgTestInvalid("{'foo':42}");
204b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgTestInvalid("{42:42}");
205b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgTestInvalid("{0:42}");
206b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgTestInvalid("{-1:42}");
207b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
208b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// Test for trailing garbage detection.
209b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgTestInvalid('42 px');
210b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgTestInvalid('42 .2');
211b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgTestInvalid('42 2');
212b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgTestInvalid('42 e1');
213b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgTestInvalid('"42" ""');
214b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgTestInvalid('"42" ""');
215b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgTestInvalid('"" ""');
216b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgTestInvalid('true ""');
217b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgTestInvalid('false ""');
218b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgTestInvalid('null ""');
219b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgTestInvalid('null ""');
220b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgTestInvalid('[] ""');
221b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgTestInvalid('[true] ""');
222b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgTestInvalid('{} ""');
223b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgTestInvalid('{"x":true} ""');
224b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgTestInvalid('"Garbage""After string"');
225b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
2263a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org// Stringify
2273a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org
2287bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgfunction TestStringify(expected, input) {
2297bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org  assertEquals(expected, JSON.stringify(input));
2307bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org  assertEquals(expected, JSON.stringify(input, null, 0));
2317bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org}
2327bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
2337bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgTestStringify("true", true);
2347bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgTestStringify("false", false);
2357bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgTestStringify("null", null);
2367bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgTestStringify("false", {toJSON: function () { return false; }});
2377bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgTestStringify("4", 4);
2387bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgTestStringify('"foo"', "foo");
2397bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgTestStringify("null", Infinity);
2407bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgTestStringify("null", -Infinity);
2417bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgTestStringify("null", NaN);
2427bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgTestStringify("4", new Number(4));
2437bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgTestStringify('"bar"', new String("bar"));
2447bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
2457bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgTestStringify('"foo\\u0000bar"', "foo\0bar");
2467bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgTestStringify('"f\\"o\'o\\\\b\\ba\\fr\\nb\\ra\\tz"',
2477bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org              "f\"o\'o\\b\ba\fr\nb\ra\tz");
2487bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
2497bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgTestStringify("[1,2,3]", [1, 2, 3]);
2503a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgassertEquals("[\n 1,\n 2,\n 3\n]", JSON.stringify([1, 2, 3], null, 1));
2513a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgassertEquals("[\n  1,\n  2,\n  3\n]", JSON.stringify([1, 2, 3], null, 2));
2523a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgassertEquals("[\n  1,\n  2,\n  3\n]",
2533a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org             JSON.stringify([1, 2, 3], null, new Number(2)));
2543a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgassertEquals("[\n^1,\n^2,\n^3\n]", JSON.stringify([1, 2, 3], null, "^"));
2553a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgassertEquals("[\n^1,\n^2,\n^3\n]",
2563a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org             JSON.stringify([1, 2, 3], null, new String("^")));
2573a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgassertEquals("[\n 1,\n 2,\n [\n  3,\n  [\n   4\n  ],\n  5\n ],\n 6,\n 7\n]",
2583a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org             JSON.stringify([1, 2, [3, [4], 5], 6, 7], null, 1));
2593a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgassertEquals("[]", JSON.stringify([], null, 1));
2603a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgassertEquals("[1,2,[3,[4],5],6,7]",
2613a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org             JSON.stringify([1, 2, [3, [4], 5], 6, 7], null));
2623a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgassertEquals("[2,4,[6,[8],10],12,14]",
2633a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org             JSON.stringify([1, 2, [3, [4], 5], 6, 7], DoubleNumbers));
2647bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgTestStringify('["a","ab","abc"]', ["a","ab","abc"]);
2657bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgTestStringify('{"a":1,"c":true}', { a : 1,
2667bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org                                    b : function() { 1 },
2677bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org                                    c : true,
2687bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org                                    d : function() { 2 } });
2697bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgTestStringify('[1,null,true,null]',
2707bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org              [1, function() { 1 }, true, function() { 2 }]);
2717bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgTestStringify('"toJSON 123"',
2727bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org              { toJSON : function() { return 'toJSON 123'; } });
2737bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgTestStringify('{"a":321}',
2747bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org              { a : { toJSON : function() { return 321; } } });
27572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orgvar counter = 0;
27672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orgassertEquals('{"getter":123}',
27772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org             JSON.stringify({ get getter() { counter++; return 123; } }));
27872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orgassertEquals(1, counter);
2797bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgassertEquals('{"getter":123}',
2807bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org             JSON.stringify({ get getter() { counter++; return 123; } },
2817bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org                            null,
2827bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org                            0));
2837bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgassertEquals(2, counter);
2847bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
2857bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgTestStringify('{"a":"abc","b":"\u1234bc"}',
2867bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org              { a : "abc", b : "\u1234bc" });
28772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
28872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
28972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orgvar a = { a : 1, b : 2 };
29072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orgdelete a.a;
2917bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgTestStringify('{"b":2}', a);
29272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
29372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orgvar b = {};
29472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orgb.__proto__ = { toJSON : function() { return 321;} };
2957bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgTestStringify("321", b);
29672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
29772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orgvar array = [""];
29872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orgvar expected = '""';
29972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orgfor (var i = 0; i < 10000; i++) {
30072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  array.push("");
30172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  expected = '"",' + expected;
30272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org}
30372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orgexpected = '[' + expected + ']';
3047bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgTestStringify(expected, array);
30572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
3063a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org
3073a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgvar circular = [1, 2, 3];
3083a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgcircular[2] = circular;
3093a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgassertThrows(function () { JSON.stringify(circular); }, TypeError);
3107bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgassertThrows(function () { JSON.stringify(circular, null, 0); }, TypeError);
3113a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org
3123a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgvar singleton = [];
3133a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgvar multiOccurrence = [singleton, singleton, singleton];
3147bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgTestStringify("[[],[],[]]", multiOccurrence);
3153a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org
3167bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgTestStringify('{"x":5,"y":6}', {x:5,y:6});
3173a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgassertEquals('{"x":5}', JSON.stringify({x:5,y:6}, ['x']));
3183a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgassertEquals('{\n "a": "b",\n "c": "d"\n}',
3193a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org             JSON.stringify({a:"b",c:"d"}, null, 1));
3203a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgassertEquals('{"y":6,"x":5}', JSON.stringify({x:5,y:6}, ['y', 'x']));
3213a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org
322a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// toJSON get string keys.
323a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvar checker = {};
324a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvar array = [checker];
325a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgchecker.toJSON = function(key) { return 1 + key; };
3267bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgTestStringify('["10"]', array);
327a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3285c838251403b0be9a882540f1922577abba4c872ager@chromium.org// The gap is capped at ten characters if specified as string.
3295c838251403b0be9a882540f1922577abba4c872ager@chromium.orgassertEquals('{\n          "a": "b",\n          "c": "d"\n}',
3305f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org              JSON.stringify({a:"b",c:"d"}, null,
3315c838251403b0be9a882540f1922577abba4c872ager@chromium.org                             "          /*characters after 10th*/"));
3325c838251403b0be9a882540f1922577abba4c872ager@chromium.org
3335c838251403b0be9a882540f1922577abba4c872ager@chromium.org//The gap is capped at ten characters if specified as number.
3345c838251403b0be9a882540f1922577abba4c872ager@chromium.orgassertEquals('{\n          "a": "b",\n          "c": "d"\n}',
3355c838251403b0be9a882540f1922577abba4c872ager@chromium.org              JSON.stringify({a:"b",c:"d"}, null, 15));
3365c838251403b0be9a882540f1922577abba4c872ager@chromium.org
3375c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Replaced wrapped primitives are unwrapped.
3385c838251403b0be9a882540f1922577abba4c872ager@chromium.orgfunction newx(k, v)  { return (k == "x") ? new v(42) : v; }
3395c838251403b0be9a882540f1922577abba4c872ager@chromium.orgassertEquals('{"x":"42"}', JSON.stringify({x: String}, newx));
3405c838251403b0be9a882540f1922577abba4c872ager@chromium.orgassertEquals('{"x":42}', JSON.stringify({x: Number}, newx));
3415c838251403b0be9a882540f1922577abba4c872ager@chromium.orgassertEquals('{"x":true}', JSON.stringify({x: Boolean}, newx));
3425c838251403b0be9a882540f1922577abba4c872ager@chromium.org
3437bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgTestStringify(undefined, undefined);
3447bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgTestStringify(undefined, function () { });
3455f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org// Arrays with missing, undefined or function elements have those elements
3465c838251403b0be9a882540f1922577abba4c872ager@chromium.org// replaced by null.
3477bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgTestStringify("[null,null,null]", [undefined,,function(){}]);
3485c838251403b0be9a882540f1922577abba4c872ager@chromium.org
3495c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Objects with undefined or function properties (including replaced properties)
3505c838251403b0be9a882540f1922577abba4c872ager@chromium.org// have those properties ignored.
3515f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgassertEquals('{}',
3525c838251403b0be9a882540f1922577abba4c872ager@chromium.org             JSON.stringify({a: undefined, b: function(){}, c: 42, d: 42},
3535f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org                            function(k, v) { if (k == "c") return undefined;
3545c838251403b0be9a882540f1922577abba4c872ager@chromium.org                                             if (k == "d") return function(){};
3555c838251403b0be9a882540f1922577abba4c872ager@chromium.org                                             return v; }));
356add848f7b25aaacf2ebb523696c074d8be15e215ager@chromium.org
357b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgTestInvalid('1); throw "foo"; (1');
358add848f7b25aaacf2ebb523696c074d8be15e215ager@chromium.org
359add848f7b25aaacf2ebb523696c074d8be15e215ager@chromium.orgvar x = 0;
360add848f7b25aaacf2ebb523696c074d8be15e215ager@chromium.orgeval("(1); x++; (1)");
361b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgTestInvalid('1); x++; (1');
3626a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
3636a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org// Test string conversion of argument.
3646a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.orgvar o = { toString: function() { return "42"; } };
3656a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.orgassertEquals(42, JSON.parse(o));
3663cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org
3673cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org
3683cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.orgfor (var i = 0; i < 65536; i++) {
3693cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org  var string = String.fromCharCode(i);
3703cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org  var encoded = JSON.stringify(string);
3713cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org  var expected = "uninitialized";
3723cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org  // Following the ES5 specification of the abstraction function Quote.
3733cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org  if (string == '"' || string == '\\') {
3743cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org    // Step 2.a
3753cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org    expected = '\\' + string;
3763cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org  } else if ("\b\t\n\r\f".indexOf(string) >= 0) {
3775f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org    // Step 2.b
3783cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org    if (string == '\b') expected = '\\b';
3793cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org    else if (string == '\t') expected = '\\t';
3803cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org    else if (string == '\n') expected = '\\n';
3813cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org    else if (string == '\f') expected = '\\f';
3823cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org    else if (string == '\r') expected = '\\r';
3833cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org  } else if (i < 32) {
3843cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org    // Step 2.c
3853cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org    if (i < 16) {
3863cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org      expected = "\\u000" + i.toString(16);
3873cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org    } else {
3883cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org      expected = "\\u00" + i.toString(16);
3893cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org    }
3903cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org  } else {
3913cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org    expected = string;
3925f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  }
3933cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org  assertEquals('"' + expected + '"', encoded, "Codepoint " + i);
3945f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org}
3955f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
3965f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
3975f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org// Ensure that wrappers and callables are handled correctly.
3985f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgvar num37 = new Number(42);
3995f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgnum37.valueOf = function() { return 37; };
4005f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
4015f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgvar numFoo = new Number(42);
4025f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgnumFoo.valueOf = "not callable";
4035f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgnumFoo.toString = function() { return "foo"; };
4045f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
4055f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgvar numTrue = new Number(42);
4065f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgnumTrue.valueOf = function() { return true; }
4075f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
4085f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgvar strFoo = new String("bar");
4095f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgstrFoo.toString = function() { return "foo"; };
4105f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
4115f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgvar str37 = new String("bar");
4125f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgstr37.toString = "not callable";
4135f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgstr37.valueOf = function() { return 37; };
4145f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
4155f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgvar strTrue = new String("bar");
4165f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgstrTrue.toString = function() { return true; }
4175f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
4185f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgvar func = function() { /* Is callable */ };
4195f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
4205f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgvar funcJSON = function() { /* Is callable */ };
4215f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgfuncJSON.toJSON = function() { return "has toJSON"; };
4225f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
4235f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgvar re = /Is callable/;
4245f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
4255f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgvar reJSON = /Is callable/;
4265f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgreJSON.toJSON = function() { return "has toJSON"; };
4275f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
4287bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgTestStringify('[37,null,1,"foo","37","true",null,"has toJSON",{},"has toJSON"]',
4297bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org              [num37, numFoo, numTrue,
4307bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org               strFoo, str37, strTrue,
4317bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org               func, funcJSON, re, reJSON]);
4325f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
4335f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
4345f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgvar oddball = Object(42);
4355f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgoddball.__proto__ = { __proto__: null, toString: function() { return true; } };
4367bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgTestStringify('1', oddball);
4375f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
4385f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgvar getCount = 0;
4395f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgvar callCount = 0;
4405f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgvar counter = { get toJSON() { getCount++;
4415f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org                               return function() { callCount++;
4425f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org                                                   return 42; }; } };
443c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org
444c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org// RegExps are not callable, so they are stringified as objects.
4457bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgTestStringify('{}', /regexp/);
4467bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgTestStringify('42', counter);
4477bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgassertEquals(2, getCount);
4487bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgassertEquals(2, callCount);
4495f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
4505f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgvar oddball2 = Object(42);
4515f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgvar oddball3 = Object("foo");
4525f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgoddball3.__proto__ = { __proto__: null,
4535f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org                       toString: "not callable",
4545f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org                       valueOf: function() { return true; } };
4555f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgoddball2.__proto__ = { __proto__: null,
4565f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org                       toJSON: function () { return oddball3; } }
4577bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgTestStringify('"true"', oddball2);
4585f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
4595f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
4605f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgvar falseNum = Object("37");
4615f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgfalseNum.__proto__ = Number.prototype;
4625f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgfalseNum.toString = function() { return 42; };
4637bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgTestStringify('"42"', falseNum);
464d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com
46571fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org// Parse an object value as __proto__.
46671fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.orgvar o1 = JSON.parse('{"__proto__":[]}');
46771fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.orgassertEquals([], o1.__proto__);
46871fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.orgassertEquals(["__proto__"], Object.keys(o1));
46971fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.orgassertEquals([], Object.getOwnPropertyDescriptor(o1, "__proto__").value);
47071fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.orgassertEquals(["__proto__"], Object.getOwnPropertyNames(o1));
47171fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.orgassertTrue(o1.hasOwnProperty("__proto__"));
47271fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.orgassertTrue(Object.prototype.isPrototypeOf(o1));
47371fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org
47471fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org// Parse a non-object value as __proto__.
47571fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.orgvar o2 = JSON.parse('{"__proto__":5}');
47671fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.orgassertEquals(5, o2.__proto__);
47771fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.orgassertEquals(["__proto__"], Object.keys(o2));
47871fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.orgassertEquals(5, Object.getOwnPropertyDescriptor(o2, "__proto__").value);
47971fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.orgassertEquals(["__proto__"], Object.getOwnPropertyNames(o2));
48071fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.orgassertTrue(o2.hasOwnProperty("__proto__"));
48171fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.orgassertTrue(Object.prototype.isPrototypeOf(o2));
482d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com
48389e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.orgvar json = '{"stuff before slash\\\\stuff after slash":"whatever"}';
4847bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgTestStringify(json, JSON.parse(json));
485