1c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org// Copyright 2011 the V8 project authors. All rights reserved.
27be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org// Redistribution and use in source and binary forms, with or without
37be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org// modification, are permitted provided that the following conditions are
47be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org// met:
57be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org//
67be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org//     * Redistributions of source code must retain the above copyright
77be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org//       notice, this list of conditions and the following disclaimer.
87be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org//     * Redistributions in binary form must reproduce the above
97be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org//       copyright notice, this list of conditions and the following
107be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org//       disclaimer in the documentation and/or other materials provided
117be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org//       with the distribution.
127be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org//     * Neither the name of Google Inc. nor the names of its
137be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org//       contributors may be used to endorse or promote products derived
147be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org//       from this software without specific prior written permission.
157be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org//
167be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
177be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
187be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
197be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
207be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
217be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
227be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
237be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
247be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
257be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
267be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
277be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org
28212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org// Flags: --allow-natives-syntax
29c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
307b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org// Check that message and name are not enumerable on Error objects.
317b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.orgvar desc = Object.getOwnPropertyDescriptor(Error.prototype, 'name');
327b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.orgassertFalse(desc['enumerable']);
337b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.orgdesc = Object.getOwnPropertyDescriptor(Error.prototype, 'message');
347b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.orgassertFalse(desc['enumerable']);
357b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
367b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.orgvar e = new Error("foobar");
377b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.orgdesc = Object.getOwnPropertyDescriptor(e, 'message');
387b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.orgassertFalse(desc['enumerable']);
397b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.orgdesc = Object.getOwnPropertyDescriptor(e, 'stack');
407b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.orgassertFalse(desc['enumerable']);
417b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
42212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.orgvar e = new Error();
43212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.orgassertFalse(e.hasOwnProperty('message'));
44212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org
457b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org// name is not tested above, but in addition we should have no enumerable
467b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org// properties, so we simply assert that.
477b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.orgfor (var v in e) {
487b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  assertUnreachable();
497b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org}
50212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org
51212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org// Check that error construction does not call setters for the
52212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org// properties on error objects in prototypes.
53212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.orgfunction fail() { assertUnreachable(); };
54212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.orgReferenceError.prototype.__defineSetter__('name', fail);
55212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.orgReferenceError.prototype.__defineSetter__('message', fail);
56212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.orgReferenceError.prototype.__defineSetter__('stack', fail);
57212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org
58212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.orgvar e = new ReferenceError();
59212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.orgassertTrue(e.hasOwnProperty('stack'));
60212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org
61212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.orgvar e = new ReferenceError('123');
62212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.orgassertTrue(e.hasOwnProperty('message'));
63212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.orgassertTrue(e.hasOwnProperty('stack'));
64212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org
65212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.orgvar e = %MakeReferenceError("my_test_error", [0, 1]);
66212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.orgassertTrue(e.hasOwnProperty('stack'));
67212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org
68212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org// Check that intercepting property access from toString is prevented for
69212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org// compiler errors. This is not specified, but allowing interception
70212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org// through a getter can leak error objects from different
71212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org// script tags in the same context in a browser setting.
72212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.orgvar errors = [SyntaxError, ReferenceError, TypeError];
73212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.orgfor (var i in errors) {
74212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  var name = errors[i].prototype.toString();
75212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  // Monkey-patch prototype.
76fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  var props = ["name", "message", "stack"];
77212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  for (var j in props) {
78212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org    errors[i].prototype.__defineGetter__(props[j], fail);
79212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  }
80212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  // String conversion should not invoke monkey-patched getters on prototype.
81212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  var e = new errors[i];
82212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  assertEquals(name, e.toString());
83212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  // Custom getters in actual objects are welcome.
84212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  e.__defineGetter__("name", function() { return "mine"; });
85212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  assertEquals("mine", e.toString());
86212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org}
87212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org
88212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org// Monkey-patching non-static errors should still be observable.
89212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.orgfunction MyError() {}
90212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.orgMyError.prototype = new Error;
91212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.orgvar errors = [Error, RangeError, EvalError, URIError, MyError];
92212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.orgfor (var i in errors) {
93212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  errors[i].prototype.__defineGetter__("name", function() { return "my"; });
94212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  errors[i].prototype.__defineGetter__("message", function() { return "moo"; });
95212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  var e = new errors[i];
96212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  assertEquals("my: moo", e.toString());
97212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org}
98212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org
99212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org
100212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.orgError.prototype.toString = Object.prototype.toString;
101212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.orgassertEquals("[object Error]", Error.prototype.toString());
102212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.orgassertEquals(Object.prototype, Error.prototype.__proto__);
103212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.orgvar e = new Error("foo");
104212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.orgassertEquals("[object Error]", e.toString());
105