Bug 1361132 TSFTextStore::GetSelection() shouldn't return if it runs on Win10 Anniversary Update or later r=m_kato draft
authorMasayuki Nakano <masayuki@d-toybox.com>
Thu, 22 Jun 2017 20:07:10 +0900
changeset 600366 733377be55d52c43ef90d6e949cb851cf4c6dcb2
parent 600295 d50abca6521baeae8ac6b07ddf843d63a1aa5f84
child 600369 7231dc958596de77118f093db2db6096efe8e078
push id65727
push usermasayuki@d-toybox.com
push dateMon, 26 Jun 2017 03:16:28 +0000
reviewersm_kato
bugs1361132, 1312302
milestone56.0a1
Bug 1361132 TSFTextStore::GetSelection() shouldn't return if it runs on Win10 Anniversary Update or later r=m_kato 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. MozReview-Commit-ID: 6cTiZ4HCO18
widget/windows/TSFTextStore.cpp
widget/windows/TSFTextStore.h
--- a/widget/windows/TSFTextStore.cpp
+++ b/widget/windows/TSFTextStore.cpp
@@ -2481,28 +2481,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;
@@ -5222,24 +5250,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
@@ -245,16 +245,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();