From 9863b3f538bbde59b2cbfe59aeec4d54119576aa Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Tue, 4 Mar 2014 10:05:08 -0800 Subject: [PATCH] Bug 977340 - Do some gymnastics to avoid tripping cx assertions when cloning exceptions from evalInWindow calls. r=gabor --- js/src/jscntxtinlines.h | 4 +++- js/src/jsfriendapi.cpp | 6 ++++++ js/src/jsfriendapi.h | 5 +++++ js/xpconnect/src/Sandbox.cpp | 6 ++++-- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/js/src/jscntxtinlines.h b/js/src/jscntxtinlines.h index 7761f5bdfcfd..338705e65887 100644 --- a/js/src/jscntxtinlines.h +++ b/js/src/jscntxtinlines.h @@ -368,7 +368,9 @@ JSContext::setPendingException(js::Value v) JS_ASSERT(!IsPoisonedValue(v)); this->throwing = true; this->unwrappedException_ = v; - js::assertSameCompartment(this, v); + // We don't use assertSameCompartment here to allow + // js::SetPendingExceptionCrossContext to work. + JS_ASSERT_IF(v.isObject(), v.toObject().compartment() == compartment()); } inline void diff --git a/js/src/jsfriendapi.cpp b/js/src/jsfriendapi.cpp index cc14abf8ec18..86246dac8c1e 100644 --- a/js/src/jsfriendapi.cpp +++ b/js/src/jsfriendapi.cpp @@ -393,6 +393,12 @@ js::GetGlobalForObjectCrossCompartment(JSObject *obj) return &obj->global(); } +JS_FRIEND_API(void) +js::SetPendingExceptionCrossContext(JSContext *cx, JS::HandleValue v) +{ + cx->setPendingException(v); +} + JS_FRIEND_API(void) js::AssertSameCompartment(JSContext *cx, JSObject *obj) { diff --git a/js/src/jsfriendapi.h b/js/src/jsfriendapi.h index 474ce9195d4d..ef6f273d8da0 100644 --- a/js/src/jsfriendapi.h +++ b/js/src/jsfriendapi.h @@ -661,6 +661,11 @@ GetObjectParentMaybeScope(JSObject *obj); JS_FRIEND_API(JSObject *) GetGlobalForObjectCrossCompartment(JSObject *obj); +// Sidestep the activeContext checking implicitly performed in +// JS_SetPendingException. +JS_FRIEND_API(void) +SetPendingExceptionCrossContext(JSContext *cx, JS::HandleValue v); + JS_FRIEND_API(void) AssertSameCompartment(JSContext *cx, JSObject *obj); diff --git a/js/xpconnect/src/Sandbox.cpp b/js/xpconnect/src/Sandbox.cpp index d0aa0b8e72c4..d6f1e96f706f 100644 --- a/js/xpconnect/src/Sandbox.cpp +++ b/js/xpconnect/src/Sandbox.cpp @@ -510,6 +510,7 @@ EvalInWindow(JSContext *cx, const nsAString &source, HandleObject scope, Mutable lineNo = 0; } + RootedObject cxGlobal(cx, JS::CurrentGlobalOrNull(cx)); { // CompileOptions must be created from the context // we will execute this script in. @@ -548,8 +549,9 @@ EvalInWindow(JSContext *cx, const nsAString &source, HandleObject scope, Mutable rval.set(UndefinedValue()); // Then clone the exception. - if (CloneNonReflectors(cx, &exn)) - JS_SetPendingException(cx, exn); + JSAutoCompartment ac(wndCx, cxGlobal); + if (CloneNonReflectors(wndCx, &exn)) + js::SetPendingExceptionCrossContext(cx, exn); return false; }