Bug 901979 - Assertion failure: !global->nativeLookup(cx, id), at ../jsobjinlines.h:1125. r=Waldo.

This commit is contained in:
Jason Orendorff 2013-10-23 11:42:25 -05:00
parent 13c4d58f7c
commit 72cba46a17
3 changed files with 64 additions and 7 deletions

View File

@ -0,0 +1,12 @@
// A proxy on the prototype chain of the global can't intercept lazy definition of globals.
// Thanks to André Bargull for this one.
var global = this;
var status = "pass";
var handler = {
get: function get(t, pk, r) { status = "FAIL get"; },
has: function has(t, pk) { status = "FAIL has"; }
};
Object.prototype.__proto__ = new Proxy(Object.create(null), handler);
Map;
assertEq(status, "pass");

View File

@ -0,0 +1,31 @@
// A proxy on the prototype chain of the global should not observe anything at
// all about lazy resolution of globals.
var global = this;
var status = "pass";
// This is a little tricky. There are two proxies.
// 1. handler is a proxy that fails the test if you try to call a method on it.
var metaHandler = {
get: _ => { status = "SMASH"; },
has: _ => { status = "SMASH"; },
invoke: _ => { status = "SMASH"; }
};
var handler = new Proxy({}, metaHandler);
// 2. Then we create a proxy using 'handler' as its handler. This means the test
// will fail if *any* method of the handler is called, not just get/has/invoke.
var angryProxy = new Proxy(Object.create(null), handler);
this.__proto__ = angryProxy;
Object.prototype.__proto__ = angryProxy;
// Trip the alarm once, to make sure the proxies are working.
this.nonExistingProperty;
assertEq(status, "SMASH");
// OK. Reset the status and run the actual test.
status = "pass";
Map;
ArrayBuffer;
Date;
assertEq(status, "pass");

View File

@ -3556,6 +3556,10 @@ DefinePropertyOrElement(typename ExecutionModeTraits<mode>::ExclusiveContextType
return true;
}
static bool
NativeLookupOwnProperty(ExclusiveContext *cx, HandleObject obj, HandleId id, unsigned flags,
MutableHandle<Shape*> shapep);
bool
js::DefineNativeProperty(ExclusiveContext *cx, HandleObject obj, HandleId id, HandleValue value,
PropertyOp getter, StrictPropertyOp setter, unsigned attrs,
@ -3579,13 +3583,11 @@ js::DefineNativeProperty(ExclusiveContext *cx, HandleObject obj, HandleId id, Ha
/*
* If we are defining a getter whose setter was already defined, or
* vice versa, finish the job via obj->changeProperty, and refresh the
* property cache line for (obj, id) to map shape.
* vice versa, finish the job via obj->changeProperty.
*/
RootedObject pobj(cx);
if (!baseops::LookupProperty<CanGC>(cx, obj, id, &pobj, &shape))
if (!NativeLookupOwnProperty(cx, obj, id, flags, &shape))
return false;
if (shape && pobj == obj) {
if (shape) {
if (IsImplicitDenseElement(shape)) {
if (!JSObject::sparsifyDenseElement(cx, obj, JSID_TO_INT(id)))
return false;
@ -3605,8 +3607,6 @@ js::DefineNativeProperty(ExclusiveContext *cx, HandleObject obj, HandleId id, Ha
} else {
shape = nullptr;
}
} else {
shape = nullptr;
}
}
@ -3800,6 +3800,20 @@ LookupOwnPropertyWithFlagsInline(ExclusiveContext *cx,
return true;
}
static bool
NativeLookupOwnProperty(ExclusiveContext *cx, HandleObject obj, HandleId id, unsigned flags,
MutableHandle<Shape*> shapep)
{
RootedObject pobj(cx);
bool done;
if (!LookupOwnPropertyWithFlagsInline<CanGC>(cx, obj, id, flags, &pobj, shapep, &done))
return false;
if (!done || pobj != obj)
shapep.set(nullptr);
return true;
}
template <AllowGC allowGC>
static JS_ALWAYS_INLINE bool
LookupPropertyWithFlagsInline(ExclusiveContext *cx,