From ac67e4fb9f748d9c751c9db03ee3edd54f96852f Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Sat, 25 Oct 2014 00:50:29 -0400 Subject: [PATCH] Bug 1083648 part 3. Change nsJSUtils::CompileFunction to take an explicit scope chain vector, not just a single scope object, and pass in the right objects in CompileEventHandlerInternal. r=bholley --- dom/base/nsJSUtils.cpp | 11 ++++++----- dom/base/nsJSUtils.h | 2 +- dom/events/EventListenerManager.cpp | 23 ++++++++++++++++++++++- dom/xbl/nsXBLProtoImplMethod.cpp | 3 ++- dom/xbl/nsXBLProtoImplProperty.cpp | 6 ++++-- dom/xbl/nsXBLPrototypeHandler.cpp | 3 ++- 6 files changed, 37 insertions(+), 11 deletions(-) diff --git a/dom/base/nsJSUtils.cpp b/dom/base/nsJSUtils.cpp index ad28704a5bd..0132b4fc94c 100644 --- a/dom/base/nsJSUtils.cpp +++ b/dom/base/nsJSUtils.cpp @@ -124,7 +124,7 @@ nsJSUtils::ReportPendingException(JSContext *aContext) nsresult nsJSUtils::CompileFunction(AutoJSAPI& jsapi, - JS::Handle aTarget, + JS::AutoObjectVector& aScopeChain, JS::CompileOptions& aOptions, const nsACString& aName, uint32_t aArgCount, @@ -135,19 +135,20 @@ nsJSUtils::CompileFunction(AutoJSAPI& jsapi, MOZ_ASSERT(jsapi.OwnsErrorReporting()); JSContext* cx = jsapi.cx(); MOZ_ASSERT(js::GetEnterCompartmentDepth(cx) > 0); - MOZ_ASSERT_IF(aTarget, js::IsObjectInContextCompartment(aTarget, cx)); + MOZ_ASSERT_IF(aScopeChain.length() != 0, + js::IsObjectInContextCompartment(aScopeChain[0], cx)); MOZ_ASSERT_IF(aOptions.versionSet, aOptions.version != JSVERSION_UNKNOWN); mozilla::DebugOnly ctx = GetScriptContextFromJSContext(cx); MOZ_ASSERT_IF(ctx, ctx->IsContextInitialized()); // Do the junk Gecko is supposed to do before calling into JSAPI. - if (aTarget) { - JS::ExposeObjectToActiveJS(aTarget); + for (size_t i = 0; i < aScopeChain.length(); ++i) { + JS::ExposeObjectToActiveJS(aScopeChain[i]); } // Compile. JS::Rooted fun(cx); - if (!JS::CompileFunction(cx, aTarget, aOptions, + if (!JS::CompileFunction(cx, aScopeChain, aOptions, PromiseFlatCString(aName).get(), aArgCount, aArgArray, PromiseFlatString(aBody).get(), diff --git a/dom/base/nsJSUtils.h b/dom/base/nsJSUtils.h index 61cf9e0ea55..d46a5a5b09d 100644 --- a/dom/base/nsJSUtils.h +++ b/dom/base/nsJSUtils.h @@ -56,7 +56,7 @@ public: static void ReportPendingException(JSContext *aContext); static nsresult CompileFunction(mozilla::dom::AutoJSAPI& jsapi, - JS::Handle aTarget, + JS::AutoObjectVector& aScopeChain, JS::CompileOptions& aOptions, const nsACString& aName, uint32_t aArgCount, diff --git a/dom/events/EventListenerManager.cpp b/dom/events/EventListenerManager.cpp index 82a55045d63..e2fea246dae 100644 --- a/dom/events/EventListenerManager.cpp +++ b/dom/events/EventListenerManager.cpp @@ -860,6 +860,19 @@ EventListenerManager::CompileEventHandlerInternal(Listener* aListener, return rv; } } + + JS::AutoObjectVector scopeChain(cx); + { // scope for curScope + // We append all the non-globals on our desired scope chain. + JS::Rooted curScope(cx, &v.toObject()); + while (curScope && !JS_IsGlobalObject(curScope)) { + if (!scopeChain.append(curScope)) { + return NS_ERROR_OUT_OF_MEMORY; + } + curScope = JS_GetParent(curScope); + } + } + if (addonId) { JS::Rooted vObj(cx, &v.toObject()); JS::Rooted addonScope(cx, xpc::GetAddonScope(cx, vObj, addonId)); @@ -867,6 +880,14 @@ EventListenerManager::CompileEventHandlerInternal(Listener* aListener, return NS_ERROR_FAILURE; } JSAutoCompartment ac(cx, addonScope); + for (size_t i = 0; i < scopeChain.length(); ++i) { + if (!JS_WrapObject(cx, scopeChain[i])) { + return NS_ERROR_FAILURE; + } + } + + // And wrap v as well, since scopeChain might be empty so we can't + // reliably use it to enter a compartment. if (!JS_WrapValue(cx, &v)) { return NS_ERROR_FAILURE; } @@ -896,7 +917,7 @@ EventListenerManager::CompileEventHandlerInternal(Listener* aListener, .setDefineOnScope(false); JS::Rooted handler(cx); - result = nsJSUtils::CompileFunction(jsapi, target, options, + result = nsJSUtils::CompileFunction(jsapi, scopeChain, options, nsAtomCString(typeAtom), argCount, argNames, *body, handler.address()); NS_ENSURE_SUCCESS(result, result); diff --git a/dom/xbl/nsXBLProtoImplMethod.cpp b/dom/xbl/nsXBLProtoImplMethod.cpp index fa745184bbc..08e980d4b06 100644 --- a/dom/xbl/nsXBLProtoImplMethod.cpp +++ b/dom/xbl/nsXBLProtoImplMethod.cpp @@ -196,7 +196,8 @@ nsXBLProtoImplMethod::CompileMember(AutoJSAPI& jsapi, const nsCString& aClassStr uncompiledMethod->mBodyText.GetLineNumber()) .setVersion(JSVERSION_LATEST); JS::Rooted methodObject(cx); - nsresult rv = nsJSUtils::CompileFunction(jsapi, JS::NullPtr(), options, cname, + JS::AutoObjectVector emptyVector(cx); + nsresult rv = nsJSUtils::CompileFunction(jsapi, emptyVector, options, cname, paramCount, const_cast(args), body, methodObject.address()); diff --git a/dom/xbl/nsXBLProtoImplProperty.cpp b/dom/xbl/nsXBLProtoImplProperty.cpp index 64a895c75fe..cc3d18ba9cc 100644 --- a/dom/xbl/nsXBLProtoImplProperty.cpp +++ b/dom/xbl/nsXBLProtoImplProperty.cpp @@ -195,7 +195,8 @@ nsXBLProtoImplProperty::CompileMember(AutoJSAPI& jsapi, const nsCString& aClassS .setVersion(JSVERSION_LATEST); nsCString name = NS_LITERAL_CSTRING("get_") + NS_ConvertUTF16toUTF8(mName); JS::Rooted getterObject(cx); - rv = nsJSUtils::CompileFunction(jsapi, JS::NullPtr(), options, name, 0, + JS::AutoObjectVector emptyVector(cx); + rv = nsJSUtils::CompileFunction(jsapi, emptyVector, options, name, 0, nullptr, getter, getterObject.address()); delete getterText; @@ -240,7 +241,8 @@ nsXBLProtoImplProperty::CompileMember(AutoJSAPI& jsapi, const nsCString& aClassS .setVersion(JSVERSION_LATEST); nsCString name = NS_LITERAL_CSTRING("set_") + NS_ConvertUTF16toUTF8(mName); JS::Rooted setterObject(cx); - rv = nsJSUtils::CompileFunction(jsapi, JS::NullPtr(), options, name, 1, + JS::AutoObjectVector emptyVector(cx); + rv = nsJSUtils::CompileFunction(jsapi, emptyVector, options, name, 1, gPropertyArgs, setter, setterObject.address()); diff --git a/dom/xbl/nsXBLPrototypeHandler.cpp b/dom/xbl/nsXBLPrototypeHandler.cpp index f3980d69e06..65716fcf8f8 100644 --- a/dom/xbl/nsXBLPrototypeHandler.cpp +++ b/dom/xbl/nsXBLPrototypeHandler.cpp @@ -373,7 +373,8 @@ nsXBLPrototypeHandler::EnsureEventHandler(AutoJSAPI& jsapi, nsIAtom* aName, .setVersion(JSVERSION_LATEST); JS::Rooted handlerFun(cx); - nsresult rv = nsJSUtils::CompileFunction(jsapi, JS::NullPtr(), options, + JS::AutoObjectVector emptyVector(cx); + nsresult rv = nsJSUtils::CompileFunction(jsapi, emptyVector, options, nsAtomCString(aName), argCount, argNames, handlerText, handlerFun.address());