Make name and message non-enumerable on Error object (this is a partial fix for issue 1215)
Review URL: http://codereview.chromium.org/7172011 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@8299 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
939011bb25
commit
4032d2165e
@ -684,18 +684,24 @@ function DefineOneShotAccessor(obj, name, fun) {
|
||||
// can't rely on 'this' being the same as 'obj'.
|
||||
var hasBeenSet = false;
|
||||
var value;
|
||||
obj.__defineGetter__(name, function () {
|
||||
function getter() {
|
||||
if (hasBeenSet) {
|
||||
return value;
|
||||
}
|
||||
hasBeenSet = true;
|
||||
value = fun(obj);
|
||||
return value;
|
||||
});
|
||||
obj.__defineSetter__(name, function (v) {
|
||||
}
|
||||
function setter(v) {
|
||||
hasBeenSet = true;
|
||||
value = v;
|
||||
});
|
||||
}
|
||||
var desc = { get: getter,
|
||||
set: setter,
|
||||
enumerable: false,
|
||||
configurable: true };
|
||||
desc = ToPropertyDescriptor(desc);
|
||||
DefineOwnProperty(obj, name, desc, true);
|
||||
}
|
||||
|
||||
function CallSite(receiver, fun, pos) {
|
||||
@ -999,15 +1005,15 @@ function DefineError(f) {
|
||||
// overwriting allows leaks of error objects between script blocks
|
||||
// in the same context in a browser setting. Therefore we fix the
|
||||
// name.
|
||||
%SetProperty(f.prototype, "name", name, READ_ONLY | DONT_DELETE);
|
||||
%SetProperty(f.prototype, "name", name, DONT_ENUM | DONT_DELETE | READ_ONLY);
|
||||
%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);
|
||||
%IgnoreAttributesAndSetProperty(this, 'stack', void 0, DONT_ENUM);
|
||||
%IgnoreAttributesAndSetProperty(this, 'arguments', void 0, DONT_ENUM);
|
||||
%IgnoreAttributesAndSetProperty(this, 'type', void 0, DONT_ENUM);
|
||||
if (m === kAddMessageAccessorsMarker) {
|
||||
// DefineOneShotAccessor always inserts a message property and
|
||||
// ignores setters.
|
||||
@ -1015,7 +1021,10 @@ function DefineError(f) {
|
||||
return FormatMessage(%NewMessageObject(obj.type, obj.arguments));
|
||||
});
|
||||
} else if (!IS_UNDEFINED(m)) {
|
||||
%IgnoreAttributesAndSetProperty(this, 'message', ToString(m));
|
||||
%IgnoreAttributesAndSetProperty(this,
|
||||
'message',
|
||||
ToString(m),
|
||||
DONT_ENUM);
|
||||
}
|
||||
captureStackTrace(this, f);
|
||||
} else {
|
||||
@ -1050,7 +1059,19 @@ DefineError(function URIError() { });
|
||||
$Error.captureStackTrace = captureStackTrace;
|
||||
|
||||
// Setup extra properties of the Error.prototype object.
|
||||
$Error.prototype.message = '';
|
||||
function setErrorMessage() {
|
||||
var desc = {value: '',
|
||||
enumerable: false,
|
||||
configurable: true,
|
||||
writable: true };
|
||||
DefineOwnProperty($Error.prototype,
|
||||
'message',
|
||||
ToPropertyDescriptor(desc),
|
||||
true);
|
||||
|
||||
}
|
||||
|
||||
setErrorMessage();
|
||||
|
||||
// Global list of error objects visited during errorToString. This is
|
||||
// used to detect cycles in error toString formatting.
|
||||
|
@ -59,3 +59,24 @@ assertEquals("ReferenceError", ReferenceError.prototype.name);
|
||||
ReferenceError.prototype.name = "not a reference error";
|
||||
assertEquals("ReferenceError", ReferenceError.prototype.name);
|
||||
|
||||
// Check that message and name are not enumerable on Error objects.
|
||||
var desc = Object.getOwnPropertyDescriptor(Error.prototype, 'name');
|
||||
assertFalse(desc['enumerable']);
|
||||
desc = Object.getOwnPropertyDescriptor(Error.prototype, 'message');
|
||||
assertFalse(desc['enumerable']);
|
||||
|
||||
var e = new Error("foobar");
|
||||
desc = Object.getOwnPropertyDescriptor(e, 'message');
|
||||
assertFalse(desc['enumerable']);
|
||||
desc = Object.getOwnPropertyDescriptor(e, 'arguments');
|
||||
assertFalse(desc['enumerable']);
|
||||
desc = Object.getOwnPropertyDescriptor(e, 'type');
|
||||
assertFalse(desc['enumerable']);
|
||||
desc = Object.getOwnPropertyDescriptor(e, 'stack');
|
||||
assertFalse(desc['enumerable']);
|
||||
|
||||
// name is not tested above, but in addition we should have no enumerable
|
||||
// properties, so we simply assert that.
|
||||
for (var v in e) {
|
||||
assertUnreachable();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user