зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1278084 part.1 Don't release TSF objects during handling a key message r=m_kato
While TIP is handling a key message, TSFTextStore shouldn't release any TSF objects since it may cause hitting a bug of TIPs. Actually, MS-IME for Japanese on Windows 10 crashes when TSFTextStore is destroyed during composition because probably it accesses some destroyed objects to request to commit composition or query contents. MozReview-Commit-ID: 9CTjHhAvG04 --HG-- extra : rebase_source : c34041962927795fe0d288aed10a96cf064b6243
This commit is contained in:
Родитель
7fd974e58a
Коммит
8cf45849ef
|
@ -1182,6 +1182,7 @@ TSFTextStore::TSFTextStore()
|
|||
, mSinkMask(0)
|
||||
, mLock(0)
|
||||
, mLockQueued(0)
|
||||
, mHandlingKeyMessage(0)
|
||||
, mLockedContent(mComposition, mSelection)
|
||||
, mRequestedAttrValues(false)
|
||||
, mIsRecordingActionsWithoutLock(false)
|
||||
|
@ -1288,9 +1289,10 @@ TSFTextStore::Destroy()
|
|||
{
|
||||
MOZ_LOG(sTextStoreLog, LogLevel::Info,
|
||||
("TSF: 0x%p TSFTextStore::Destroy(), mLock=%s, "
|
||||
"mComposition.IsComposing()=%s",
|
||||
"mComposition.IsComposing()=%s, mHandlingKeyMessage=%u",
|
||||
this, GetLockFlagNameStr(mLock).get(),
|
||||
GetBoolName(mComposition.IsComposing())));
|
||||
GetBoolName(mComposition.IsComposing()),
|
||||
mHandlingKeyMessage));
|
||||
|
||||
mDestroyed = true;
|
||||
|
||||
|
@ -1319,6 +1321,27 @@ TSFTextStore::Destroy()
|
|||
mLockedContent.Clear();
|
||||
mSelection.MarkDirty();
|
||||
|
||||
// If this is called during handling a keydown or keyup message, we should
|
||||
// put off to release TSF objects until it completely finishes since
|
||||
// MS-IME for Japanese refers some objects without grabbing them.
|
||||
if (!mHandlingKeyMessage) {
|
||||
ReleaseTSFObjects();
|
||||
}
|
||||
|
||||
MOZ_LOG(sTextStoreLog, LogLevel::Info,
|
||||
("TSF: 0x%p TSFTextStore::Destroy() succeeded", this));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
TSFTextStore::ReleaseTSFObjects()
|
||||
{
|
||||
MOZ_ASSERT(!mHandlingKeyMessage);
|
||||
|
||||
MOZ_LOG(sTextStoreLog, LogLevel::Info,
|
||||
("TSF: 0x%p TSFTextStore::ReleaseTSFObjects()", this));
|
||||
|
||||
mContext = nullptr;
|
||||
if (mDocumentMgr) {
|
||||
mDocumentMgr->Pop(TF_POPF_ALL);
|
||||
|
@ -1330,14 +1353,14 @@ TSFTextStore::Destroy()
|
|||
|
||||
if (!mMouseTrackers.IsEmpty()) {
|
||||
MOZ_LOG(sTextStoreLog, LogLevel::Debug,
|
||||
("TSF: 0x%p TSFTextStore::Destroy(), removing a mouse tracker...",
|
||||
("TSF: 0x%p TSFTextStore::ReleaseTSFObjects(), "
|
||||
"removing a mouse tracker...",
|
||||
this));
|
||||
mMouseTrackers.Clear();
|
||||
}
|
||||
|
||||
MOZ_LOG(sTextStoreLog, LogLevel::Info,
|
||||
("TSF: 0x%p TSFTextStore::Destroy() succeeded", this));
|
||||
return true;
|
||||
MOZ_LOG(sTextStoreLog, LogLevel::Debug,
|
||||
("TSF: 0x%p TSFTextStore::ReleaseTSFObjects() completed", this));
|
||||
}
|
||||
|
||||
STDMETHODIMP
|
||||
|
@ -5470,7 +5493,14 @@ TSFTextStore::ProcessRawKeyMessage(const MSG& aMsg)
|
|||
if (FAILED(hr) || !eaten) {
|
||||
return false;
|
||||
}
|
||||
RefPtr<TSFTextStore> textStore(sEnabledTextStore);
|
||||
if (textStore) {
|
||||
textStore->OnStartToHandleKeyMessage();
|
||||
}
|
||||
hr = sKeystrokeMgr->KeyDown(aMsg.wParam, aMsg.lParam, &eaten);
|
||||
if (textStore) {
|
||||
textStore->OnEndHandlingKeyMessage();
|
||||
}
|
||||
return SUCCEEDED(hr) && eaten;
|
||||
}
|
||||
if (aMsg.message == WM_KEYUP) {
|
||||
|
@ -5479,7 +5509,14 @@ TSFTextStore::ProcessRawKeyMessage(const MSG& aMsg)
|
|||
if (FAILED(hr) || !eaten) {
|
||||
return false;
|
||||
}
|
||||
RefPtr<TSFTextStore> textStore(sEnabledTextStore);
|
||||
if (textStore) {
|
||||
textStore->OnStartToHandleKeyMessage();
|
||||
}
|
||||
hr = sKeystrokeMgr->KeyUp(aMsg.wParam, aMsg.lParam, &eaten);
|
||||
if (textStore) {
|
||||
textStore->OnEndHandlingKeyMessage();
|
||||
}
|
||||
return SUCCEEDED(hr) && eaten;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -248,6 +248,7 @@ protected:
|
|||
|
||||
bool Init(nsWindowBase* aWidget);
|
||||
bool Destroy();
|
||||
void ReleaseTSFObjects();
|
||||
|
||||
bool IsReadLock(DWORD aLock) const
|
||||
{
|
||||
|
@ -348,6 +349,21 @@ protected:
|
|||
// 0 if no lock is queued, otherwise TS_LF_* indicating the queue lock
|
||||
DWORD mLockQueued;
|
||||
|
||||
uint32_t mHandlingKeyMessage;
|
||||
void OnStartToHandleKeyMessage() { ++mHandlingKeyMessage; }
|
||||
void OnEndHandlingKeyMessage()
|
||||
{
|
||||
MOZ_ASSERT(mHandlingKeyMessage);
|
||||
if (--mHandlingKeyMessage) {
|
||||
return;
|
||||
}
|
||||
// If TSFTextStore instance is destroyed during handling key message(s),
|
||||
// release all TSF objects when all nested key messages have been handled.
|
||||
if (mDestroyed) {
|
||||
ReleaseTSFObjects();
|
||||
}
|
||||
}
|
||||
|
||||
class Composition final
|
||||
{
|
||||
public:
|
||||
|
|
Загрузка…
Ссылка в новой задаче