OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
11 // with the distribution. | 11 // with the distribution. |
12 // * Neither the name of Google Inc. nor the names of its | 12 // * Neither the name of Google Inc. nor the names of its |
13 // contributors may be used to endorse or promote products derived | 13 // contributors may be used to endorse or promote products derived |
14 // from this software without specific prior written permission. | 14 // from this software without specific prior written permission. |
15 // | 15 // |
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | 27 |
28 var e = new Error(); | 28 // Flags: --allow-natives-syntax |
29 assertFalse(e.hasOwnProperty('message')); | |
30 Error.prototype.toString = Object.prototype.toString; | |
31 assertEquals("[object Error]", Error.prototype.toString()); | |
32 assertEquals(Object.prototype, Error.prototype.__proto__); | |
33 | |
34 // Check that error construction does not call setters for the | |
35 // properties on error objects in prototypes. | |
36 function fail() { assertTrue(false); }; | |
37 ReferenceError.prototype.__defineSetter__('stack', fail); | |
38 ReferenceError.prototype.__defineSetter__('message', fail); | |
39 ReferenceError.prototype.__defineSetter__('type', fail); | |
40 ReferenceError.prototype.__defineSetter__('arguments', fail); | |
41 var e0 = new ReferenceError(); | |
42 var e1 = new ReferenceError('123'); | |
43 assertTrue(e1.hasOwnProperty('message')); | |
44 assertTrue(e0.hasOwnProperty('stack')); | |
45 assertTrue(e1.hasOwnProperty('stack')); | |
46 assertTrue(e0.hasOwnProperty('type')); | |
47 assertTrue(e1.hasOwnProperty('type')); | |
48 assertTrue(e0.hasOwnProperty('arguments')); | |
49 assertTrue(e1.hasOwnProperty('arguments')); | |
50 | |
51 // Check that the name property on error prototypes is read-only and | |
52 // dont-delete. This is not specified, but allowing overwriting the | |
53 // name property with a getter can leaks error objects from different | |
54 // script tags in the same context in a browser setting. We therefore | |
55 // disallow changes to the name property on error objects. | |
56 assertEquals("ReferenceError", ReferenceError.prototype.name); | |
57 delete ReferenceError.prototype.name; | |
58 assertEquals("ReferenceError", ReferenceError.prototype.name); | |
59 ReferenceError.prototype.name = "not a reference error"; | |
60 assertEquals("ReferenceError", ReferenceError.prototype.name); | |
61 | 29 |
62 // Check that message and name are not enumerable on Error objects. | 30 // Check that message and name are not enumerable on Error objects. |
63 var desc = Object.getOwnPropertyDescriptor(Error.prototype, 'name'); | 31 var desc = Object.getOwnPropertyDescriptor(Error.prototype, 'name'); |
64 assertFalse(desc['enumerable']); | 32 assertFalse(desc['enumerable']); |
65 desc = Object.getOwnPropertyDescriptor(Error.prototype, 'message'); | 33 desc = Object.getOwnPropertyDescriptor(Error.prototype, 'message'); |
66 assertFalse(desc['enumerable']); | 34 assertFalse(desc['enumerable']); |
67 | 35 |
68 var e = new Error("foobar"); | 36 var e = new Error("foobar"); |
69 desc = Object.getOwnPropertyDescriptor(e, 'message'); | 37 desc = Object.getOwnPropertyDescriptor(e, 'message'); |
70 assertFalse(desc['enumerable']); | 38 assertFalse(desc['enumerable']); |
71 desc = Object.getOwnPropertyDescriptor(e, 'arguments'); | 39 desc = Object.getOwnPropertyDescriptor(e, 'arguments'); |
72 assertFalse(desc['enumerable']); | 40 assertFalse(desc['enumerable']); |
73 desc = Object.getOwnPropertyDescriptor(e, 'type'); | 41 desc = Object.getOwnPropertyDescriptor(e, 'type'); |
74 assertFalse(desc['enumerable']); | 42 assertFalse(desc['enumerable']); |
75 desc = Object.getOwnPropertyDescriptor(e, 'stack'); | 43 desc = Object.getOwnPropertyDescriptor(e, 'stack'); |
76 assertFalse(desc['enumerable']); | 44 assertFalse(desc['enumerable']); |
77 | 45 |
| 46 var e = new Error(); |
| 47 assertFalse(e.hasOwnProperty('message')); |
| 48 |
78 // name is not tested above, but in addition we should have no enumerable | 49 // name is not tested above, but in addition we should have no enumerable |
79 // properties, so we simply assert that. | 50 // properties, so we simply assert that. |
80 for (var v in e) { | 51 for (var v in e) { |
81 assertUnreachable(); | 52 assertUnreachable(); |
82 } | 53 } |
| 54 |
| 55 // Check that error construction does not call setters for the |
| 56 // properties on error objects in prototypes. |
| 57 function fail() { assertUnreachable(); }; |
| 58 ReferenceError.prototype.__defineSetter__('name', fail); |
| 59 ReferenceError.prototype.__defineSetter__('message', fail); |
| 60 ReferenceError.prototype.__defineSetter__('type', fail); |
| 61 ReferenceError.prototype.__defineSetter__('arguments', fail); |
| 62 ReferenceError.prototype.__defineSetter__('stack', fail); |
| 63 |
| 64 var e = new ReferenceError(); |
| 65 assertTrue(e.hasOwnProperty('stack')); |
| 66 assertTrue(e.hasOwnProperty('type')); |
| 67 assertTrue(e.hasOwnProperty('arguments')); |
| 68 |
| 69 var e = new ReferenceError('123'); |
| 70 assertTrue(e.hasOwnProperty('message')); |
| 71 assertTrue(e.hasOwnProperty('stack')); |
| 72 assertTrue(e.hasOwnProperty('type')); |
| 73 assertTrue(e.hasOwnProperty('arguments')); |
| 74 |
| 75 var e = %MakeReferenceError("my_test_error", [0, 1]); |
| 76 assertTrue(e.hasOwnProperty('stack')); |
| 77 assertTrue(e.hasOwnProperty('type')); |
| 78 assertTrue(e.hasOwnProperty('arguments')); |
| 79 assertEquals("my_test_error", e.type) |
| 80 |
| 81 // Check that intercepting property access from toString is prevented for |
| 82 // compiler errors. This is not specified, but allowing interception |
| 83 // through a getter can leak error objects from different |
| 84 // script tags in the same context in a browser setting. |
| 85 var errors = [SyntaxError, ReferenceError, TypeError]; |
| 86 for (var i in errors) { |
| 87 var name = errors[i].prototype.toString(); |
| 88 // Monkey-patch prototype. |
| 89 var props = ["name", "message", "type", "arguments", "stack"]; |
| 90 for (var j in props) { |
| 91 errors[i].prototype.__defineGetter__(props[j], fail); |
| 92 } |
| 93 // String conversion should not invoke monkey-patched getters on prototype. |
| 94 var e = new errors[i]; |
| 95 assertEquals(name, e.toString()); |
| 96 // Custom getters in actual objects are welcome. |
| 97 e.__defineGetter__("name", function() { return "mine"; }); |
| 98 assertEquals("mine", e.toString()); |
| 99 } |
| 100 |
| 101 // Monkey-patching non-static errors should still be observable. |
| 102 function MyError() {} |
| 103 MyError.prototype = new Error; |
| 104 var errors = [Error, RangeError, EvalError, URIError, MyError]; |
| 105 for (var i in errors) { |
| 106 errors[i].prototype.__defineGetter__("name", function() { return "my"; }); |
| 107 errors[i].prototype.__defineGetter__("message", function() { return "moo"; }); |
| 108 var e = new errors[i]; |
| 109 assertEquals("my: moo", e.toString()); |
| 110 } |
| 111 |
| 112 |
| 113 Error.prototype.toString = Object.prototype.toString; |
| 114 assertEquals("[object Error]", Error.prototype.toString()); |
| 115 assertEquals(Object.prototype, Error.prototype.__proto__); |
| 116 var e = new Error("foo"); |
| 117 assertEquals("[object Error]", e.toString()); |
OLD | NEW |