From 78a637e5f76eeb1a73a78cda519d75f862725aa3 Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Fri, 28 Apr 2017 20:09:55 +0900 Subject: [PATCH] Bug 1359547 EventStateManager should grab IMEContentObserver with local variable before calling HandleQueryContentEvent() r=smaug --- dom/events/EventStateManager.cpp | 3 ++- dom/events/IMEContentObserver.cpp | 16 ++++++++++++++++ dom/events/IMEContentObserver.h | 2 ++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/dom/events/EventStateManager.cpp b/dom/events/EventStateManager.cpp index e8896c513398..5c42f7f00590 100644 --- a/dom/events/EventStateManager.cpp +++ b/dom/events/EventStateManager.cpp @@ -912,7 +912,8 @@ EventStateManager::HandleQueryContentEvent(WidgetQueryContentEvent* aEvent) // If there is an IMEContentObserver, we need to handle QueryContentEvent // with it. if (mIMEContentObserver) { - mIMEContentObserver->HandleQueryContentEvent(aEvent); + RefPtr contentObserver = mIMEContentObserver; + contentObserver->HandleQueryContentEvent(aEvent); return; } diff --git a/dom/events/IMEContentObserver.cpp b/dom/events/IMEContentObserver.cpp index a8ad3659c96d..71ba3fa5b88b 100644 --- a/dom/events/IMEContentObserver.cpp +++ b/dom/events/IMEContentObserver.cpp @@ -549,6 +549,12 @@ IMEContentObserver::Destroy() } } +bool +IMEContentObserver::Destroyed() const +{ + return !mWidget; +} + void IMEContentObserver::DisconnectFromEventStateManager() { @@ -784,6 +790,16 @@ IMEContentObserver::HandleQueryContentEvent(WidgetQueryContentEvent* aEvent) mIsHandlingQueryContentEvent = true; ContentEventHandler handler(GetPresContext()); nsresult rv = handler.HandleQueryContentEvent(aEvent); + if (NS_WARN_IF(Destroyed())) { + // If this has already destroyed during querying the content, the query + // is outdated even if it's succeeded. So, make the query fail. + aEvent->mSucceeded = false; + MOZ_LOG(sIMECOLog, LogLevel::Warning, + ("0x%p IMEContentObserver::HandleQueryContentEvent(), WARNING, " + "IMEContentObserver has been destroyed during the query, " + "making the query fail", this)); + return rv; + } if (!IsInitializedWithPlugin() && NS_WARN_IF(aEvent->mReply.mContentsRoot != mRootContent)) { diff --git a/dom/events/IMEContentObserver.h b/dom/events/IMEContentObserver.h index 51b9c0b56280..063557dcc868 100644 --- a/dom/events/IMEContentObserver.h +++ b/dom/events/IMEContentObserver.h @@ -76,6 +76,8 @@ public: void Init(nsIWidget* aWidget, nsPresContext* aPresContext, nsIContent* aContent, nsIEditor* aEditor); void Destroy(); + bool Destroyed() const; + /** * IMEContentObserver is stored by EventStateManager during observing. * DisconnectFromEventStateManager() is called when EventStateManager stops