Do not allow accessors to intercept getting/setting properties on
authorager@chromium.org <ager@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 13 Jan 2011 06:56:54 +0000 (06:56 +0000)
committerager@chromium.org <ager@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 13 Jan 2011 06:56:54 +0000 (06:56 +0000)
error objects under construction and string conversions.

Review URL: http://codereview.chromium.org/6146009

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6291 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/messages.js
test/mjsunit/error-constructors.js

index c19f4a9a683a40b6c8cdefae14893008419c8481..441244bc8797ae28ac0960620847958b4ef9944e 100644 (file)
@@ -946,12 +946,20 @@ function DefineError(f) {
   f.prototype.name = name;
   %SetCode(f, function(m) {
     if (%_IsConstructCall()) {
+      // Define all the expected properties directly on the error
+      // object. This avoids going through getters and setters defined
+      // on prototype objects.
+      %IgnoreAttributesAndSetProperty(this, 'stack', void 0);
+      %IgnoreAttributesAndSetProperty(this, 'arguments', void 0);
+      %IgnoreAttributesAndSetProperty(this, 'type', void 0);
       if (m === kAddMessageAccessorsMarker) {
+        // DefineOneShotAccessor always inserts a message property and
+        // ignores setters.
         DefineOneShotAccessor(this, 'message', function (obj) {
           return FormatMessage({type: obj.type, args: obj.arguments});
         });
       } else if (!IS_UNDEFINED(m)) {
-        this.message = ToString(m);
+        %IgnoreAttributesAndSetProperty(this, 'message', ToString(m));
       }
       captureStackTrace(this, f);
     } else {
@@ -992,8 +1000,8 @@ $Error.prototype.message = '';
   if (type && !this.hasOwnProperty("message")) {
     return this.name + ": " + FormatMessage({ type: type, args: this.arguments });
   }
-  var message = this.message;
-  return this.name + (message ? (": " + message) : "");
+  var message = this.hasOwnProperty("message") ? (": " + this.message) : "";
+  return this.name + message;
 }, DONT_ENUM);
 
 
index ca2aa060a587211eefcbd375596cf8d34e7597b0..6b7671d19e395e0449b0e48af48ef5140d869f6a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2009 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -30,3 +30,22 @@ assertFalse(e.hasOwnProperty('message'));
 Error.prototype.toString = Object.prototype.toString;
 assertEquals("[object Error]", Error.prototype.toString());
 assertEquals(Object.prototype, Error.prototype.__proto__);
+
+// Check that error construction does not call setters for the
+// properties on error objects in prototypes.
+function fail() { assertTrue(false); };
+ReferenceError.prototype.__defineSetter__('stack', fail);
+ReferenceError.prototype.__defineSetter__('message', fail);
+ReferenceError.prototype.__defineSetter__('type', fail);
+ReferenceError.prototype.__defineSetter__('arguments', fail);
+var e0 = new ReferenceError();
+var e1 = new ReferenceError('123');
+assertTrue(e1.hasOwnProperty('message'));
+assertTrue(e0.hasOwnProperty('stack'));
+assertTrue(e1.hasOwnProperty('stack'));
+assertTrue(e0.hasOwnProperty('type'));
+assertTrue(e1.hasOwnProperty('type'));
+assertTrue(e0.hasOwnProperty('arguments'));
+assertTrue(e1.hasOwnProperty('arguments'));
+
+