Do CPDF_CMap loading in the constructors.

This allows CPDF_CMapManager to hold and return const CPDF_CMaps.

Change-Id: I1ee0f8a81ea719cc6d7569026aa523bf2437c64f
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/59217
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/font/cpdf_cidfont.cpp b/core/fpdfapi/font/cpdf_cidfont.cpp
index 63fcffb..2160d42 100644
--- a/core/fpdfapi/font/cpdf_cidfont.cpp
+++ b/core/fpdfapi/font/cpdf_cidfont.cpp
@@ -365,8 +365,7 @@
   } else if (CPDF_Stream* pStream = pEncoding->AsStream()) {
     auto pAcc = pdfium::MakeRetain<CPDF_StreamAcc>(pStream);
     pAcc->LoadAllDataFiltered();
-    m_pCMap = pdfium::MakeRetain<CPDF_CMap>();
-    m_pCMap->LoadEmbedded(pAcc->GetSpan());
+    m_pCMap = pdfium::MakeRetain<CPDF_CMap>(pAcc->GetSpan());
   } else {
     return false;
   }
diff --git a/core/fpdfapi/font/cpdf_cidfont.h b/core/fpdfapi/font/cpdf_cidfont.h
index ea97f26..ce00e1d 100644
--- a/core/fpdfapi/font/cpdf_cidfont.h
+++ b/core/fpdfapi/font/cpdf_cidfont.h
@@ -75,7 +75,7 @@
   void LoadSubstFont();
   wchar_t GetUnicodeFromCharCode(uint32_t charcode) const;
 
-  RetainPtr<CPDF_CMap> m_pCMap;
+  RetainPtr<const CPDF_CMap> m_pCMap;
   UnownedPtr<const CPDF_CID2UnicodeMap> m_pCID2UnicodeMap;
   RetainPtr<CPDF_StreamAcc> m_pStreamAcc;
   std::unique_ptr<CFX_CTTGSUBTable> m_pTTGSUBTable;
diff --git a/core/fpdfapi/font/cpdf_cmap.cpp b/core/fpdfapi/font/cpdf_cmap.cpp
index 0ff688f..e30e50d 100644
--- a/core/fpdfapi/font/cpdf_cmap.cpp
+++ b/core/fpdfapi/font/cpdf_cmap.cpp
@@ -237,22 +237,17 @@
 
 }  // namespace
 
-CPDF_CMap::CPDF_CMap() = default;
-
-CPDF_CMap::~CPDF_CMap() = default;
-
-void CPDF_CMap::LoadPredefined(const ByteString& bsName) {
-  if (bsName == "Identity-H" || bsName == "Identity-V") {
+CPDF_CMap::CPDF_CMap(const ByteString& bsPredefinedName) {
+  if (bsPredefinedName == "Identity-H" || bsPredefinedName == "Identity-V") {
     m_Coding = CIDCODING_CID;
-    m_bVertical = bsName.Last() == 'V';
+    m_bVertical = bsPredefinedName.Last() == 'V';
     m_bLoaded = true;
     return;
   }
-  ByteString cmapid = bsName;
+  ByteString cmapid = bsPredefinedName;
   m_bVertical = cmapid.Last() == 'V';
-  if (cmapid.GetLength() > 2) {
+  if (cmapid.GetLength() > 2)
     cmapid = cmapid.Left(cmapid.GetLength() - 2);
-  }
   const PredefinedCMap* map = nullptr;
   for (size_t i = 0; i < FX_ArraySize(g_PredefinedCMaps); ++i) {
     if (cmapid == ByteStringView(g_PredefinedCMaps[i].m_pName)) {
@@ -275,24 +270,26 @@
     }
   }
   m_pEmbedMap = FindEmbeddedCMap(
-      CPDF_FontGlobals::GetInstance()->GetEmbeddedCharset(m_Charset), bsName);
+      CPDF_FontGlobals::GetInstance()->GetEmbeddedCharset(m_Charset),
+      bsPredefinedName);
   if (!m_pEmbedMap)
     return;
 
   m_bLoaded = true;
 }
 
-void CPDF_CMap::LoadEmbedded(pdfium::span<const uint8_t> data) {
-  m_DirectCharcodeToCIDTable = std::vector<uint16_t>(65536);
+CPDF_CMap::CPDF_CMap(pdfium::span<const uint8_t> spEmbeddedData)
+    : m_DirectCharcodeToCIDTable(65536) {
   CPDF_CMapParser parser(this);
-  CPDF_SimpleParser syntax(data);
+  CPDF_SimpleParser syntax(spEmbeddedData);
   while (1) {
     ByteStringView word = syntax.GetWord();
-    if (word.IsEmpty()) {
+    if (word.IsEmpty())
       break;
-    }
+
     parser.ParseWord(word);
   }
+
   if (m_CodingScheme == MixedFourBytes && parser.HasAdditionalMappings()) {
     m_AdditionalCharcodeToCIDMappings = parser.TakeAdditionalMappings();
     std::sort(
@@ -304,6 +301,8 @@
   }
 }
 
+CPDF_CMap::~CPDF_CMap() = default;
+
 uint16_t CPDF_CMap::CIDFromCharCode(uint32_t charcode) const {
   if (m_Coding == CIDCODING_CID)
     return static_cast<uint16_t>(charcode);
diff --git a/core/fpdfapi/font/cpdf_cmap.h b/core/fpdfapi/font/cpdf_cmap.h
index 92a62e3..f0f3a94 100644
--- a/core/fpdfapi/font/cpdf_cmap.h
+++ b/core/fpdfapi/font/cpdf_cmap.h
@@ -50,9 +50,6 @@
   template <typename T, typename... Args>
   friend RetainPtr<T> pdfium::MakeRetain(Args&&... args);
 
-  void LoadPredefined(const ByteString& name);
-  void LoadEmbedded(pdfium::span<const uint8_t> data);
-
   bool IsLoaded() const { return m_bLoaded; }
   bool IsVertWriting() const { return m_bVertical; }
 
@@ -85,7 +82,8 @@
   }
 
  private:
-  CPDF_CMap();
+  explicit CPDF_CMap(const ByteString& bsPredefinedName);
+  explicit CPDF_CMap(pdfium::span<const uint8_t> spEmbeddedData);
   ~CPDF_CMap() override;
 
   bool m_bLoaded = false;
diff --git a/core/fpdfapi/font/cpdf_cmapmanager.cpp b/core/fpdfapi/font/cpdf_cmapmanager.cpp
index 60ec26e..bc47ad0 100644
--- a/core/fpdfapi/font/cpdf_cmapmanager.cpp
+++ b/core/fpdfapi/font/cpdf_cmapmanager.cpp
@@ -12,30 +12,28 @@
 #include "core/fpdfapi/font/cpdf_cmap.h"
 #include "third_party/base/ptr_util.h"
 
-CPDF_CMapManager::CPDF_CMapManager() {}
+CPDF_CMapManager::CPDF_CMapManager() = default;
 
-CPDF_CMapManager::~CPDF_CMapManager() {}
+CPDF_CMapManager::~CPDF_CMapManager() = default;
 
-RetainPtr<CPDF_CMap> CPDF_CMapManager::GetPredefinedCMap(
+RetainPtr<const CPDF_CMap> CPDF_CMapManager::GetPredefinedCMap(
     const ByteString& name) {
   auto it = m_CMaps.find(name);
   if (it != m_CMaps.end())
     return it->second;
 
-  RetainPtr<CPDF_CMap> pCMap = LoadPredefinedCMap(name);
+  RetainPtr<const CPDF_CMap> pCMap = LoadPredefinedCMap(name);
   if (!name.IsEmpty())
     m_CMaps[name] = pCMap;
 
   return pCMap;
 }
 
-RetainPtr<CPDF_CMap> CPDF_CMapManager::LoadPredefinedCMap(ByteString name) {
+RetainPtr<const CPDF_CMap> CPDF_CMapManager::LoadPredefinedCMap(
+    ByteString name) {
   if (!name.IsEmpty() && name[0] == '/')
     name = name.Right(name.GetLength() - 1);
-
-  auto pCMap = pdfium::MakeRetain<CPDF_CMap>();
-  pCMap->LoadPredefined(name);
-  return pCMap;
+  return pdfium::MakeRetain<CPDF_CMap>(name);
 }
 
 CPDF_CID2UnicodeMap* CPDF_CMapManager::GetCID2UnicodeMap(CIDSet charset) {
diff --git a/core/fpdfapi/font/cpdf_cmapmanager.h b/core/fpdfapi/font/cpdf_cmapmanager.h
index af61e3f..a4f451c 100644
--- a/core/fpdfapi/font/cpdf_cmapmanager.h
+++ b/core/fpdfapi/font/cpdf_cmapmanager.h
@@ -19,14 +19,14 @@
   CPDF_CMapManager();
   ~CPDF_CMapManager();
 
-  RetainPtr<CPDF_CMap> GetPredefinedCMap(const ByteString& name);
+  RetainPtr<const CPDF_CMap> GetPredefinedCMap(const ByteString& name);
   CPDF_CID2UnicodeMap* GetCID2UnicodeMap(CIDSet charset);
 
  private:
-  RetainPtr<CPDF_CMap> LoadPredefinedCMap(ByteString name);
+  RetainPtr<const CPDF_CMap> LoadPredefinedCMap(ByteString name);
   std::unique_ptr<CPDF_CID2UnicodeMap> LoadCID2UnicodeMap(CIDSet charset);
 
-  std::map<ByteString, RetainPtr<CPDF_CMap>> m_CMaps;
+  std::map<ByteString, RetainPtr<const CPDF_CMap>> m_CMaps;
   std::unique_ptr<CPDF_CID2UnicodeMap> m_CID2UnicodeMaps[6];
 };
 
diff --git a/testing/fuzzers/pdf_cmap_fuzzer.cc b/testing/fuzzers/pdf_cmap_fuzzer.cc
index c827b7c..180a6a7 100644
--- a/testing/fuzzers/pdf_cmap_fuzzer.cc
+++ b/testing/fuzzers/pdf_cmap_fuzzer.cc
@@ -11,6 +11,6 @@
   if (size > 256 * 1024)
     return 0;
 
-  pdfium::MakeRetain<CPDF_CMap>()->LoadEmbedded(pdfium::make_span(data, size));
+  pdfium::MakeRetain<CPDF_CMap>(pdfium::make_span(data, size));
   return 0;
 }