Cache CFGAS_FontMgr::GetFontByUnicode() failures on Windows.

Non-Windows does this already, which is why it can handle fuzzers that
throws the same invalid unicode character at it efficiently. Whereas
Windows tries to do the same failing font load repeatedly.

BUG=chromium:895469

Change-Id: I6780d1ec0881222348e05a5a63e7b2238f39a3a6
Reviewed-on: https://pdfium-review.googlesource.com/c/44251
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
diff --git a/xfa/fgas/font/cfgas_fontmgr.cpp b/xfa/fgas/font/cfgas_fontmgr.cpp
index 8881be7..22e97f0 100644
--- a/xfa/fgas/font/cfgas_fontmgr.cpp
+++ b/xfa/fgas/font/cfgas_fontmgr.cpp
@@ -27,6 +27,23 @@
 #include "xfa/fgas/font/cfx_fontsourceenum_file.h"
 #endif
 
+namespace {
+
+bool VerifyUnicode(const RetainPtr<CFGAS_GEFont>& pFont, wchar_t wcUnicode) {
+  FXFT_Face pFace = pFont->GetDevFont()->GetFace();
+  FXFT_CharMap charmap = FXFT_Get_Face_Charmap(pFace);
+  if (FXFT_Select_Charmap(pFace, FXFT_ENCODING_UNICODE) != 0)
+    return false;
+
+  if (FXFT_Get_Char_Index(pFace, wcUnicode) == 0) {
+    FXFT_Set_Charmap(pFace, charmap);
+    return false;
+  }
+  return true;
+}
+
+}  // namespace
+
 #if _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
 
 namespace {
@@ -182,6 +199,11 @@
     return nullptr;
 
   pFont->SetLogicalFontStyle(dwFontStyles);
+  if (!VerifyUnicode(pFont, wUnicode)) {
+    m_FailedUnicodesSet.insert(wUnicode);
+    return nullptr;
+  }
+
   m_Hash2Fonts[dwHash].push_back(pFont);
   return pFont;
 }
@@ -779,26 +801,6 @@
 
 #endif  // _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
 
-namespace {
-
-bool VerifyUnicode(const RetainPtr<CFGAS_GEFont>& pFont, wchar_t wcUnicode) {
-  if (!pFont)
-    return false;
-
-  FXFT_Face pFace = pFont->GetDevFont()->GetFace();
-  FXFT_CharMap charmap = FXFT_Get_Face_Charmap(pFace);
-  if (FXFT_Select_Charmap(pFace, FXFT_ENCODING_UNICODE) != 0)
-    return false;
-
-  if (FXFT_Get_Char_Index(pFace, wcUnicode) == 0) {
-    FXFT_Set_Charmap(pFace, charmap);
-    return false;
-  }
-  return true;
-}
-
-}  // namespace
-
 RetainPtr<CFGAS_GEFont> CFGAS_FontMgr::GetFontByCodePage(
     uint16_t wCodePage,
     uint32_t dwFontStyles,
@@ -857,10 +859,8 @@
     wchar_t wUnicode,
     uint32_t dwFontStyles,
     const wchar_t* pszFontFamily) {
-#if _FX_PLATFORM_ != _FX_PLATFORM_WINDOWS_
   if (pdfium::ContainsKey(m_FailedUnicodesSet, wUnicode))
     return nullptr;
-#endif  // _FX_PLATFORM_ != _FX_PLATFORM_WINDOWS_
 
   const FGAS_FONTUSB* x = FGAS_GetUnicodeBitField(wUnicode);
   uint16_t wCodePage = x ? x->wCodePage : 0xFFFF;
diff --git a/xfa/fgas/font/cfgas_fontmgr.h b/xfa/fgas/font/cfgas_fontmgr.h
index b784bed..389f96a 100644
--- a/xfa/fgas/font/cfgas_fontmgr.h
+++ b/xfa/fgas/font/cfgas_fontmgr.h
@@ -145,6 +145,7 @@
 #endif  // _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
 
   std::map<uint32_t, std::vector<RetainPtr<CFGAS_GEFont>>> m_Hash2Fonts;
+  std::set<wchar_t> m_FailedUnicodesSet;
 
 #if _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
   std::deque<FX_FONTDESCRIPTOR> m_FontFaces;
@@ -155,7 +156,6 @@
       m_Hash2CandidateList;
   std::map<RetainPtr<CFGAS_GEFont>, RetainPtr<IFX_SeekableReadStream>>
       m_IFXFont2FileRead;
-  std::set<wchar_t> m_FailedUnicodesSet;
 #endif  // _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
 };