Check for dead wrappers in CallerGetterImpl/CallerSetterImpl
parent
e93b35424f
commit
4b3a33f781
|
@ -288,6 +288,12 @@ CallerGetterImpl(JSContext* cx, const CallArgs& args)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (JS_IsDeadWrapper(callerObj)) {
|
||||||
|
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
|
||||||
|
JSMSG_DEAD_OBJECT);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
JSFunction* callerFun = &callerObj->as<JSFunction>();
|
JSFunction* callerFun = &callerObj->as<JSFunction>();
|
||||||
MOZ_ASSERT(!callerFun->isBuiltin(), "non-builtin iterator returned a builtin?");
|
MOZ_ASSERT(!callerFun->isBuiltin(), "non-builtin iterator returned a builtin?");
|
||||||
|
|
||||||
|
@ -314,54 +320,14 @@ CallerSetterImpl(JSContext* cx, const CallArgs& args)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(IsFunction(args.thisv()));
|
MOZ_ASSERT(IsFunction(args.thisv()));
|
||||||
|
|
||||||
// Beware! This function can be invoked on *any* function! It can't
|
// We just have to return |undefined|, but first we call CallerGetterImpl
|
||||||
// assume it'll never be invoked on natives, strict mode functions, bound
|
// because we need the same strict-mode and security checks.
|
||||||
// functions, or anything else that ordinarily has immutable .caller
|
|
||||||
// defined with [[ThrowTypeError]].
|
if (!CallerGetterImpl(cx, args)) {
|
||||||
RootedFunction fun(cx, &args.thisv().toObject().as<JSFunction>());
|
return false;
|
||||||
if (!CallerRestrictions(cx, fun))
|
}
|
||||||
return false;
|
|
||||||
|
|
||||||
// Return |undefined| unless an error must be thrown.
|
|
||||||
args.rval().setUndefined();
|
args.rval().setUndefined();
|
||||||
|
|
||||||
// We can almost just return |undefined| here -- but if the caller function
|
|
||||||
// was strict mode code, we still have to throw a TypeError. This requires
|
|
||||||
// computing the caller, checking that no security boundaries are crossed,
|
|
||||||
// and throwing a TypeError if the resulting caller is strict.
|
|
||||||
|
|
||||||
NonBuiltinScriptFrameIter iter(cx);
|
|
||||||
if (!AdvanceToActiveCallLinear(cx, iter, fun))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
++iter;
|
|
||||||
while (!iter.done() && iter.isEvalFrame())
|
|
||||||
++iter;
|
|
||||||
|
|
||||||
if (iter.done() || !iter.isFunctionFrame())
|
|
||||||
return true;
|
|
||||||
|
|
||||||
RootedObject caller(cx, iter.callee(cx));
|
|
||||||
if (!cx->compartment()->wrap(cx, &caller)) {
|
|
||||||
cx->clearPendingException();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we don't have full access to the caller, or the caller is not strict,
|
|
||||||
// return undefined. Otherwise throw a TypeError.
|
|
||||||
JSObject* callerObj = CheckedUnwrap(caller);
|
|
||||||
if (!callerObj)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
JSFunction* callerFun = &callerObj->as<JSFunction>();
|
|
||||||
MOZ_ASSERT(!callerFun->isBuiltin(), "non-builtin iterator returned a builtin?");
|
|
||||||
|
|
||||||
if (callerFun->strict()) {
|
|
||||||
JS_ReportErrorFlagsAndNumberASCII(cx, JSREPORT_ERROR, GetErrorMessage, nullptr,
|
|
||||||
JSMSG_CALLER_IS_STRICT);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue