зеркало из https://github.com/mozilla/gecko-dev.git
Bug 658909 - Force |this| computation in SandboxCallableProxyHandler::call when using Xrays. r=bz
Comment says it all.
This commit is contained in:
Родитель
8e9287775b
Коммит
1ee0eb91c2
|
@ -3064,12 +3064,37 @@ xpc::SandboxCallableProxyHandler::call(JSContext *cx, JSObject *proxy,
|
|||
MOZ_ASSERT(js::GetObjectJSClass(sandboxGlobal) == &SandboxClass);
|
||||
|
||||
// If our this object is the sandbox global, we call with this set to the
|
||||
// original proto instead. Note that we very carefully avoid using JS_THIS
|
||||
// or JS_THIS_OBJECT here, because we do NOT want to box undefined into the
|
||||
// global. Instead, we just pass it through to our callable, and it will
|
||||
// compute the global based on its own scope chain, which will do the right
|
||||
// thing.
|
||||
JS::Value thisVal = JS_THIS_VALUE(cx, vp);
|
||||
// original proto instead.
|
||||
//
|
||||
// There are two different ways we can compute |this|. If we use
|
||||
// JS_THIS_VALUE, we'll get the bonafide |this| value as passed by the
|
||||
// caller, which may be undefined if a global function was invoked without
|
||||
// an explicit invocant. If we use JS_THIS or JS_THIS_OBJECT, the |this|
|
||||
// in |vp| will be coerced to the global, which is not the correct
|
||||
// behavior in ES5 strict mode. And we have no way to compute strictness
|
||||
// here.
|
||||
//
|
||||
// The naive approach is simply to use JS_THIS_VALUE here. If |this| was
|
||||
// explicit, we can remap it appropriately. If it was implicit, then we
|
||||
// leave it as undefined, and let the callee sort it out. Since the callee
|
||||
// is generally in the same compartment as its global (eg the Window's
|
||||
// compartment, not the Sandbox's), the callee will generally compute the
|
||||
// correct |this|.
|
||||
//
|
||||
// However, this breaks down in the Xray case. If the sandboxPrototype
|
||||
// is an Xray wrapper, then we'll end up reifying the native methods in
|
||||
// the Sandbox's scope, which means that they'll compute |this| to be the
|
||||
// Sandbox, breaking old-style XPC_WN_CallMethod methods.
|
||||
//
|
||||
// Luckily, the intent of Xrays is to provide a vanilla view of a foreign
|
||||
// DOM interface, which means that we don't care about script-enacted
|
||||
// strictness in the prototype's home compartment. Indeed, since DOM
|
||||
// methods are always non-strict, we can just assume non-strict semantics
|
||||
// if the sandboxPrototype is an Xray Wrapper, which lets us appropriately
|
||||
// remap |this|.
|
||||
JS::Value thisVal =
|
||||
WrapperFactory::IsXrayWrapper(sandboxProxy) ? JS_THIS(cx, vp)
|
||||
: JS_THIS_VALUE(cx, vp);
|
||||
if (thisVal == ObjectValue(*sandboxGlobal)) {
|
||||
thisVal = ObjectValue(*js::GetProxyTargetObject(sandboxProxy));
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче