Bug 1361132 - TSFTextStore::GetSelection() shouldn't return if it runs on Win10 Anniversary Update or later. r=m_kato, a=IanN CLOSED TREE DONTBUILD SEAMONKEY_2_49_ESR_RELBRANCH
authorMasayuki Nakano <masayuki@d-toybox.com>
Thu, 22 Jun 2017 20:07:10 +0900
branchSEAMONKEY_2_49_ESR_RELBRANCH
changeset 357502 1f9aa563be7a7ce9c4f49915ab4485ee11654b61
parent 357501 daee65cb6a9be052a5433ca527bfa27691b01659
child 357503 bf889819fe7ec334da163a3fba9ff93582a12735
push id7834
push userfrgrahl@gmx.net
push dateSun, 13 Jan 2019 12:17:02 +0000
treeherdermozilla-esr52@6e4ad8a8f2e8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersm_kato, IanN
bugs1361132, 1312302
milestone52.9.1
Bug 1361132 - TSFTextStore::GetSelection() shouldn't return if it runs on Win10 Anniversary Update or later. r=m_kato, a=IanN CLOSED TREE DONTBUILD mozilla-esr52 SEAMONKEY_2_49_ESR_RELBRANCH This is remaining cases of bug 1312302. TSF may set focus to context when it receives focus related message. In such case, TSF tries to retrieve selection but TSFTextStore::GetSelection() returns E_FAIL due to still not initialized, TSF crashes. This patch moves the hack to TSFTextStore::GetSelection() and restrict to work only on problematic versions of Windows 10.
widget/windows/TSFTextStore.cpp
widget/windows/TSFTextStore.h
--- a/widget/windows/TSFTextStore.cpp
+++ b/widget/windows/TSFTextStore.cpp
@@ -2117,28 +2117,56 @@ TSFTextStore::GetSelection(ULONG ulIndex
     MOZ_LOG(sTextStoreLog, LogLevel::Error,
       ("0x%p   TSFTextStore::GetSelection() FAILED due to "
        "unsupported selection", this));
     return TS_E_NOSELECTION;
   }
 
   Selection& selectionForTSF = SelectionForTSFRef();
   if (selectionForTSF.IsDirty()) {
+    if (DoNotReturnErrorFromGetSelection()) {
+      AutoSetTemporarySelection temprarySetter(selectionForTSF);
+      *pSelection = selectionForTSF.ACP();
+      *pcFetched = 1;
+      MOZ_LOG(sTextStoreLog, LogLevel::Info,
+        ("0x%p   TSFTextStore::GetSelection() returns fake selection range "
+         "for avoiding a crash in TSF, "
+         "acpStart=%d, acpEnd=%d (length=%d), reverted=%s",
+         this, selectionForTSF.StartOffset(), selectionForTSF.EndOffset(),
+         selectionForTSF.Length(), GetBoolName(selectionForTSF.IsReversed())));
+      return S_OK;
+    }
     MOZ_LOG(sTextStoreLog, LogLevel::Error,
       ("0x%p   TSFTextStore::GetSelection() FAILED due to "
        "SelectionForTSFRef() failure", this));
     return E_FAIL;
   }
   *pSelection = selectionForTSF.ACP();
   *pcFetched = 1;
   MOZ_LOG(sTextStoreLog, LogLevel::Info,
-    ("0x%p   TSFTextStore::GetSelection() succeeded", this));
+    ("0x%p   TSFTextStore::GetSelection() succeeded, "
+     "acpStart=%d, acpEnd=%d (length=%d), reverted=%s",
+     this, selectionForTSF.StartOffset(), selectionForTSF.EndOffset(),
+     selectionForTSF.Length(), GetBoolName(selectionForTSF.IsReversed())));
   return S_OK;
 }
 
+// static
+bool
+TSFTextStore::DoNotReturnErrorFromGetSelection()
+{
+  // There is a crash bug of TSF if we return error from GetSelection().
+  // That was introduced in Anniversary Update (build 14393, see bug 1312302)
+  // TODO: We should avoid to run this hack on fixed builds.  When we get
+  //       exact build number, we should get back here.
+  static bool sTSFMayCrashIfGetSelectionReturnsError =
+    IsWindows10BuildOrLater(14393);
+  return sTSFMayCrashIfGetSelectionReturnsError;
+}
+
 bool
 TSFTextStore::IsComposingInContent() const
 {
   if (!mDispatcher) {
     return false;
   }
   if (!mDispatcher->IsInNativeInputTransaction()) {
     return false;
@@ -4856,24 +4884,17 @@ TSFTextStore::CreateAndSetFocus(nsWindow
     newDocMgr->GetTop(getter_AddRefs(topContext));
     if (topContext && topContext != textStore->mContext) {
       MarkContextAsKeyboardDisabled(topContext);
     }
   }
 
   HRESULT hr;
   RefPtr<ITfThreadMgr> threadMgr = sThreadMgr;
-  {
-    // Windows 10's softwware keyboard requires that SetSelection must be
-    // always successful into SetFocus.  If returning error, it might crash
-    // into TextInputFramework.dll.
-    AutoSetTemporarySelection setSelection(textStore->SelectionForTSFRef());
-
-    hr = threadMgr->SetFocus(newDocMgr);
-  }
+  hr = threadMgr->SetFocus(newDocMgr);
 
   if (NS_WARN_IF(FAILED(hr))) {
     MOZ_LOG(sTextStoreLog, LogLevel::Error,
       ("  TSFTextStore::CreateAndSetFocus() FAILED due to "
        "ITfTheadMgr::SetFocus() failure"));
     EnsureToDestroyAndReleaseEnabledTextStoreIf(textStore);
     return false;
   }
--- a/widget/windows/TSFTextStore.h
+++ b/widget/windows/TSFTextStore.h
@@ -248,16 +248,21 @@ public:
    */
   static bool IsIMM_IMEActive();
 
   /**
    * Returns true if active TIP is MS-IME for Japanese.
    */
   static bool IsMSJapaneseIMEActive();
 
+  /**
+   * Returns true if TSF may crash if GetSelection() returns E_FAIL.
+   */
+  static bool DoNotReturnErrorFromGetSelection();
+
 #ifdef DEBUG
   // Returns true when keyboard layout has IME (TIP).
   static bool     CurrentKeyboardLayoutHasIME();
 #endif // #ifdef DEBUG
 
 protected:
   TSFTextStore();
   ~TSFTextStore();