diff options
author | wolfbeast <mcwerewolf@wolfbeast.com> | 2019-03-22 12:06:40 +0100 |
---|---|---|
committer | wolfbeast <mcwerewolf@wolfbeast.com> | 2019-03-22 12:06:40 +0100 |
commit | a7013083d3620b683457d96c302c50a56f30e070 (patch) | |
tree | 80a13ea1cb37e9fbe9e05e2b52e1c25d84876683 | |
parent | ff9877cfe46e0c62e5e69af99445c7ca4738fbd5 (diff) | |
download | UXP-a7013083d3620b683457d96c302c50a56f30e070.tar UXP-a7013083d3620b683457d96c302c50a56f30e070.tar.gz UXP-a7013083d3620b683457d96c302c50a56f30e070.tar.lz UXP-a7013083d3620b683457d96c302c50a56f30e070.tar.xz UXP-a7013083d3620b683457d96c302c50a56f30e070.zip |
Check for dead wrappers in CallerGetterImpl/CallerSetterImpl.
This also removes code duplication by making CallerSetterImpl call
CallerGetterImpl.
-rw-r--r-- | js/src/jsfun.cpp | 58 |
1 files changed, 12 insertions, 46 deletions
diff --git a/js/src/jsfun.cpp b/js/src/jsfun.cpp index 863871df9..98311be2f 100644 --- a/js/src/jsfun.cpp +++ b/js/src/jsfun.cpp @@ -288,6 +288,12 @@ CallerGetterImpl(JSContext* cx, const CallArgs& args) return true; } + if (JS_IsDeadWrapper(callerObj)) { + JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, + JSMSG_DEAD_OBJECT); + return false; + } + JSFunction* callerFun = &callerObj->as<JSFunction>(); 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())); - // Beware! This function can be invoked on *any* function! It can't - // assume it'll never be invoked on natives, strict mode functions, bound - // functions, or anything else that ordinarily has immutable .caller - // defined with [[ThrowTypeError]]. - RootedFunction fun(cx, &args.thisv().toObject().as<JSFunction>()); - if (!CallerRestrictions(cx, fun)) - return false; - - // Return |undefined| unless an error must be thrown. - 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; + // We just have to return |undefined|, but first we call CallerGetterImpl
+ // because we need the same strict-mode and security checks.
+
+ if (!CallerGetterImpl(cx, args)) { + return false;
} + args.rval().setUndefined(); return true; } |