зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1480678 part 7 - Use CallbackObject's callback global for realm entering in more places. r=bz
This commit is contained in:
Родитель
59ff5de1a2
Коммит
4af62d6c9e
|
@ -378,7 +378,7 @@ CallbackObjectHolderBase::ToXPCOMCallback(CallbackObject* aCallback,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
JSAutoRealmAllowCCW ar(cx, callback);
|
||||
JSAutoRealm ar(cx, aCallback->CallbackGlobalOrNull());
|
||||
|
||||
RefPtr<nsXPCWrappedJS> wrappedJS;
|
||||
nsresult rv =
|
||||
|
|
|
@ -366,7 +366,7 @@ protected:
|
|||
// Put mAr after mAutoEntryScript so that we exit the realm before we
|
||||
// pop the script settings stack. Though in practice we'll often manually
|
||||
// order those two things.
|
||||
Maybe<JSAutoRealmAllowCCW> mAr;
|
||||
Maybe<JSAutoRealm> mAr;
|
||||
|
||||
// An ErrorResult to possibly re-throw exceptions on and whether
|
||||
// we should re-throw them.
|
||||
|
|
|
@ -15290,7 +15290,7 @@ class CGJSImplClass(CGBindingImplClass):
|
|||
}
|
||||
|
||||
// Now define it on our chrome object
|
||||
JSAutoRealmAllowCCW ar(aCx, mImpl->CallbackOrNull());
|
||||
JSAutoRealm ar(aCx, mImpl->CallbackGlobalOrNull());
|
||||
if (!JS_WrapObject(aCx, &obj)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -1770,8 +1770,9 @@ Console::ProcessCallData(JSContext* aCx, ConsoleCallData* aData,
|
|||
// tempted to do that anywhere else, talk to said module owner first.
|
||||
|
||||
// aCx and aArguments are in the same compartment.
|
||||
JS::Rooted<JSObject*> targetScope(aCx, xpc::PrivilegedJunkScope());
|
||||
if (NS_WARN_IF(!PopulateConsoleNotificationInTheTargetScope(aCx, aArguments,
|
||||
xpc::PrivilegedJunkScope(),
|
||||
targetScope,
|
||||
&eventValue, aData))) {
|
||||
return;
|
||||
}
|
||||
|
@ -1810,15 +1811,14 @@ Console::ProcessCallData(JSContext* aCx, ConsoleCallData* aData,
|
|||
bool
|
||||
Console::PopulateConsoleNotificationInTheTargetScope(JSContext* aCx,
|
||||
const Sequence<JS::Value>& aArguments,
|
||||
JSObject* aTargetScope,
|
||||
JS::Handle<JSObject*> aTargetScope,
|
||||
JS::MutableHandle<JS::Value> aEventValue,
|
||||
ConsoleCallData* aData)
|
||||
{
|
||||
MOZ_ASSERT(aCx);
|
||||
MOZ_ASSERT(aData);
|
||||
MOZ_ASSERT(aTargetScope);
|
||||
|
||||
JS::Rooted<JSObject*> targetScope(aCx, aTargetScope);
|
||||
MOZ_ASSERT(JS_IsGlobalObject(aTargetScope));
|
||||
|
||||
ConsoleStackEntry frame;
|
||||
if (aData->mTopStackFrame) {
|
||||
|
@ -1927,7 +1927,7 @@ Console::PopulateConsoleNotificationInTheTargetScope(JSContext* aCx,
|
|||
aData->mCountValue);
|
||||
}
|
||||
|
||||
JSAutoRealmAllowCCW ar2(aCx, targetScope);
|
||||
JSAutoRealm ar2(aCx, aTargetScope);
|
||||
|
||||
if (NS_WARN_IF(!ToJSValue(aCx, event, aEventValue))) {
|
||||
return false;
|
||||
|
@ -2692,16 +2692,18 @@ Console::NotifyHandler(JSContext* aCx, const Sequence<JS::Value>& aArguments,
|
|||
|
||||
JS::Rooted<JS::Value> value(aCx);
|
||||
|
||||
JS::Rooted<JSObject*> callable(aCx, mConsoleEventNotifier->CallableOrNull());
|
||||
if (NS_WARN_IF(!callable)) {
|
||||
JS::Rooted<JSObject*> callableGlobal(aCx,
|
||||
mConsoleEventNotifier->CallbackGlobalOrNull());
|
||||
if (NS_WARN_IF(!callableGlobal)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// aCx and aArguments are in the same compartment because this method is
|
||||
// called directly when a Console.something() runs.
|
||||
// mConsoleEventNotifier->Callable() is the scope where value will be sent to.
|
||||
// mConsoleEventNotifier->CallbackGlobal() is the scope where value will be
|
||||
// sent to.
|
||||
if (NS_WARN_IF(!PopulateConsoleNotificationInTheTargetScope(aCx, aArguments,
|
||||
callable,
|
||||
callableGlobal,
|
||||
&value,
|
||||
aCallData))) {
|
||||
return;
|
||||
|
|
|
@ -239,14 +239,14 @@ private:
|
|||
// - the system-principal scope when we want to dispatch the ConsoleEvent to
|
||||
// nsIConsoleAPIStorage (See the comment in Console.cpp about the use of
|
||||
// xpc::PrivilegedJunkScope()
|
||||
// - the mConsoleEventNotifier->Callable() scope when we want to notify this
|
||||
// - the mConsoleEventNotifier->CallableGlobal() when we want to notify this
|
||||
// handler about a new ConsoleEvent.
|
||||
// - It can be the global from the JSContext when RetrieveConsoleEvents is
|
||||
// called.
|
||||
bool
|
||||
PopulateConsoleNotificationInTheTargetScope(JSContext* aCx,
|
||||
const Sequence<JS::Value>& aArguments,
|
||||
JSObject* aTargetScope,
|
||||
JS::Handle<JSObject*> aTargetScope,
|
||||
JS::MutableHandle<JS::Value> aValue,
|
||||
ConsoleCallData* aData);
|
||||
|
||||
|
|
|
@ -1615,9 +1615,12 @@ EventListenerManager::GetListenerInfo(nsCOMArray<nsIEventListenerInfo>* aList)
|
|||
}
|
||||
|
||||
JS::Rooted<JSObject*> callback(RootingCx());
|
||||
JS::Rooted<JSObject*> callbackGlobal(RootingCx());
|
||||
if (JSEventHandler* handler = listener.GetJSEventHandler()) {
|
||||
if (handler->GetTypedEventHandler().HasEventHandler()) {
|
||||
callback = handler->GetTypedEventHandler().Ptr()->CallableOrNull();
|
||||
CallbackFunction* callbackFun = handler->GetTypedEventHandler().Ptr();
|
||||
callback = callbackFun->CallableOrNull();
|
||||
callbackGlobal = callbackFun->CallbackGlobalOrNull();
|
||||
if (!callback) {
|
||||
// This will be null for cross-compartment event listeners
|
||||
// which have been destroyed.
|
||||
|
@ -1625,7 +1628,9 @@ EventListenerManager::GetListenerInfo(nsCOMArray<nsIEventListenerInfo>* aList)
|
|||
}
|
||||
}
|
||||
} else if (listener.mListenerType == Listener::eWebIDLListener) {
|
||||
callback = listener.mListener.GetWebIDLCallback()->CallbackOrNull();
|
||||
EventListener* listenerCallback = listener.mListener.GetWebIDLCallback();
|
||||
callback = listenerCallback->CallbackOrNull();
|
||||
callbackGlobal = listenerCallback->CallbackGlobalOrNull();
|
||||
if (!callback) {
|
||||
// This will be null for cross-compartment event listeners
|
||||
// which have been destroyed.
|
||||
|
@ -1634,7 +1639,7 @@ EventListenerManager::GetListenerInfo(nsCOMArray<nsIEventListenerInfo>* aList)
|
|||
}
|
||||
|
||||
RefPtr<EventListenerInfo> info =
|
||||
new EventListenerInfo(eventType, callback,
|
||||
new EventListenerInfo(eventType, callback, callbackGlobal,
|
||||
listener.mFlags.mCapture,
|
||||
listener.mFlags.mAllowUntrustedEvents,
|
||||
listener.mFlags.mInSystemGroup);
|
||||
|
|
|
@ -82,15 +82,22 @@ EventListenerChange::GetCountOfEventListenerChangesAffectingAccessibility(
|
|||
|
||||
EventListenerInfo::EventListenerInfo(const nsAString& aType,
|
||||
JS::Handle<JSObject*> aScriptedListener,
|
||||
JS::Handle<JSObject*> aScriptedListenerGlobal,
|
||||
bool aCapturing,
|
||||
bool aAllowsUntrusted,
|
||||
bool aInSystemEventGroup)
|
||||
: mType(aType)
|
||||
, mScriptedListener(aScriptedListener)
|
||||
, mScriptedListenerGlobal(aScriptedListenerGlobal)
|
||||
, mCapturing(aCapturing)
|
||||
, mAllowsUntrusted(aAllowsUntrusted)
|
||||
, mInSystemEventGroup(aInSystemEventGroup)
|
||||
{
|
||||
if (aScriptedListener) {
|
||||
MOZ_ASSERT(JS_IsGlobalObject(aScriptedListenerGlobal));
|
||||
js::AssertSameCompartment(aScriptedListener, aScriptedListenerGlobal);
|
||||
}
|
||||
|
||||
HoldJSObjects(this);
|
||||
}
|
||||
|
||||
|
@ -106,10 +113,12 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
|||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(EventListenerInfo)
|
||||
tmp->mScriptedListener = nullptr;
|
||||
tmp->mScriptedListenerGlobal = nullptr;
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(EventListenerInfo)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mScriptedListener)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mScriptedListenerGlobal)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(EventListenerInfo)
|
||||
|
@ -152,7 +161,7 @@ NS_IMETHODIMP
|
|||
EventListenerInfo::GetListenerObject(JSContext* aCx,
|
||||
JS::MutableHandle<JS::Value> aObject)
|
||||
{
|
||||
Maybe<JSAutoRealmAllowCCW> ar;
|
||||
Maybe<JSAutoRealm> ar;
|
||||
GetJSVal(aCx, ar, aObject);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -165,12 +174,12 @@ NS_IMPL_ISUPPORTS(EventListenerService, nsIEventListenerService)
|
|||
|
||||
bool
|
||||
EventListenerInfo::GetJSVal(JSContext* aCx,
|
||||
Maybe<JSAutoRealmAllowCCW>& aAr,
|
||||
Maybe<JSAutoRealm>& aAr,
|
||||
JS::MutableHandle<JS::Value> aJSVal)
|
||||
{
|
||||
if (mScriptedListener) {
|
||||
aJSVal.setObject(*mScriptedListener);
|
||||
aAr.emplace(aCx, mScriptedListener);
|
||||
aAr.emplace(aCx, mScriptedListenerGlobal);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -184,7 +193,7 @@ EventListenerInfo::ToSource(nsAString& aResult)
|
|||
aResult.SetIsVoid(true);
|
||||
|
||||
AutoSafeJSContext cx;
|
||||
Maybe<JSAutoRealmAllowCCW> ar;
|
||||
Maybe<JSAutoRealm> ar;
|
||||
JS::Rooted<JS::Value> v(cx);
|
||||
if (GetJSVal(cx, ar, &v)) {
|
||||
JSString* str = JS_ValueToSource(cx, v);
|
||||
|
|
|
@ -49,6 +49,7 @@ class EventListenerInfo final : public nsIEventListenerInfo
|
|||
public:
|
||||
EventListenerInfo(const nsAString& aType,
|
||||
JS::Handle<JSObject*> aScriptedListener,
|
||||
JS::Handle<JSObject*> aScriptedListenerGlobal,
|
||||
bool aCapturing,
|
||||
bool aAllowsUntrusted,
|
||||
bool aInSystemEventGroup);
|
||||
|
@ -61,11 +62,16 @@ protected:
|
|||
virtual ~EventListenerInfo();
|
||||
|
||||
bool GetJSVal(JSContext* aCx,
|
||||
Maybe<JSAutoRealmAllowCCW>& aAr,
|
||||
Maybe<JSAutoRealm>& aAr,
|
||||
JS::MutableHandle<JS::Value> aJSVal);
|
||||
|
||||
nsString mType;
|
||||
JS::Heap<JSObject*> mScriptedListener; // May be null.
|
||||
// mScriptedListener may be a cross-compartment wrapper so we cannot use it
|
||||
// with JSAutoRealm because CCWs are not associated with a single realm. We
|
||||
// use this global instead (must be same-compartment with mScriptedListener
|
||||
// and must be non-null if mScriptedListener is non-null).
|
||||
JS::Heap<JSObject*> mScriptedListenerGlobal;
|
||||
bool mCapturing;
|
||||
bool mAllowsUntrusted;
|
||||
bool mInSystemEventGroup;
|
||||
|
|
Загрузка…
Ссылка в новой задаче