Get rid of recursive constructor calls in JBIG2_Context

Instead, make it private and provide a static Create() function
that cobbles two objects together in the appropriate way.

Change-Id: I5df061c1bd2776e62e2782ca8016361dcfc535d1
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/55331
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/core/fxcodec/codec/ccodec_jbig2module.cpp b/core/fxcodec/codec/ccodec_jbig2module.cpp
index e9c3be2..16fd0e3 100644
--- a/core/fxcodec/codec/ccodec_jbig2module.cpp
+++ b/core/fxcodec/codec/ccodec_jbig2module.cpp
@@ -60,9 +60,8 @@
   pJbig2Context->m_dest_buf = dest_buf;
   pJbig2Context->m_dest_pitch = dest_pitch;
   memset(dest_buf, 0, height * dest_pitch);
-  pJbig2Context->m_pContext = pdfium::MakeUnique<CJBig2_Context>(
-      global_stream, src_stream, pJBig2DocumentContext->GetSymbolDictCache(),
-      false);
+  pJbig2Context->m_pContext = CJBig2_Context::Create(
+      global_stream, src_stream, pJBig2DocumentContext->GetSymbolDictCache());
   bool succeeded = pJbig2Context->m_pContext->GetFirstPage(
       dest_buf, width, height, dest_pitch, pPause);
   return Decode(pJbig2Context, succeeded);
diff --git a/core/fxcodec/jbig2/JBig2_Context.cpp b/core/fxcodec/jbig2/JBig2_Context.cpp
index d2c243c..2a0c09d 100644
--- a/core/fxcodec/jbig2/JBig2_Context.cpp
+++ b/core/fxcodec/jbig2/JBig2_Context.cpp
@@ -51,26 +51,29 @@
 static_assert(kSymbolDictCacheMaxSize > 0,
               "Symbol Dictionary Cache must have non-zero size");
 
-CJBig2_Context::CJBig2_Context(const RetainPtr<CPDF_StreamAcc>& pGlobalStream,
-                               const RetainPtr<CPDF_StreamAcc>& pSrcStream,
+// static
+std::unique_ptr<CJBig2_Context> CJBig2_Context::Create(
+    const RetainPtr<CPDF_StreamAcc>& pGlobalStream,
+    const RetainPtr<CPDF_StreamAcc>& pSrcStream,
+    std::list<CJBig2_CachePair>* pSymbolDictCache) {
+  auto result = pdfium::WrapUnique(
+      new CJBig2_Context(pSrcStream, pSymbolDictCache, false));
+  if (pGlobalStream && pGlobalStream->GetSize() > 0) {
+    result->m_pGlobalContext = pdfium::WrapUnique(
+        new CJBig2_Context(pGlobalStream, pSymbolDictCache, true));
+  }
+  return result;
+}
+
+CJBig2_Context::CJBig2_Context(const RetainPtr<CPDF_StreamAcc>& pSrcStream,
                                std::list<CJBig2_CachePair>* pSymbolDictCache,
                                bool bIsGlobal)
     : m_pStream(pdfium::MakeUnique<CJBig2_BitStream>(
           pSrcStream->GetSpan(),
           pSrcStream->GetStream() ? pSrcStream->GetStream()->GetObjNum() : 0)),
       m_HuffmanTables(CJBig2_HuffmanTable::kNumHuffmanTables),
-      m_bInPage(false),
-      m_bBufSpecified(false),
-      m_PauseStep(10),
-      m_ProcessingStatus(FXCODEC_STATUS_FRAME_READY),
-      m_dwOffset(0),
-      m_pSymbolDictCache(pSymbolDictCache),
-      m_bIsGlobal(bIsGlobal) {
-  if (pGlobalStream && pGlobalStream->GetSize() > 0) {
-    m_pGlobalContext = pdfium::MakeUnique<CJBig2_Context>(
-        nullptr, pGlobalStream, pSymbolDictCache, true);
-  }
-}
+      m_bIsGlobal(bIsGlobal),
+      m_pSymbolDictCache(pSymbolDictCache) {}
 
 CJBig2_Context::~CJBig2_Context() {}
 
diff --git a/core/fxcodec/jbig2/JBig2_Context.h b/core/fxcodec/jbig2/JBig2_Context.h
index 2e7bbb4..ec9d4a7 100644
--- a/core/fxcodec/jbig2/JBig2_Context.h
+++ b/core/fxcodec/jbig2/JBig2_Context.h
@@ -34,10 +34,11 @@
 
 class CJBig2_Context {
  public:
-  CJBig2_Context(const RetainPtr<CPDF_StreamAcc>& pGlobalStream,
-                 const RetainPtr<CPDF_StreamAcc>& pSrcStream,
-                 std::list<CJBig2_CachePair>* pSymbolDictCache,
-                 bool bIsGlobal);
+  static std::unique_ptr<CJBig2_Context> Create(
+      const RetainPtr<CPDF_StreamAcc>& pGlobalStream,
+      const RetainPtr<CPDF_StreamAcc>& pSrcStream,
+      std::list<CJBig2_CachePair>* pSymbolDictCache);
+
   ~CJBig2_Context();
 
   static bool HuffmanAssignCode(JBig2HuffmanCode* SBSYMCODES, uint32_t NTEMP);
@@ -52,6 +53,10 @@
   FXCODEC_STATUS GetProcessingStatus() const { return m_ProcessingStatus; }
 
  private:
+  CJBig2_Context(const RetainPtr<CPDF_StreamAcc>& pSrcStream,
+                 std::list<CJBig2_CachePair>* pSymbolDictCache,
+                 bool bIsGlobal);
+
   JBig2_Result DecodeSequential(PauseIndicatorIface* pPause);
 
   CJBig2_Segment* FindSegmentByNumber(uint32_t dwNumber);
@@ -76,7 +81,6 @@
   JBig2_Result ParseRegionInfo(JBig2RegionInfo* pRI);
 
   std::vector<JBig2HuffmanCode> DecodeSymbolIDHuffmanTable(uint32_t SBNUMSYMS);
-
   const CJBig2_HuffmanTable* GetHuffmanTable(size_t idx);
 
   std::unique_ptr<CJBig2_Context> m_pGlobalContext;
@@ -85,18 +89,18 @@
   std::vector<std::unique_ptr<JBig2PageInfo>> m_PageInfoList;
   std::unique_ptr<CJBig2_Image> m_pPage;
   std::vector<std::unique_ptr<CJBig2_HuffmanTable>> m_HuffmanTables;
-  bool m_bInPage;
-  bool m_bBufSpecified;
-  int32_t m_PauseStep;
-  FXCODEC_STATUS m_ProcessingStatus;
+  const bool m_bIsGlobal;
+  bool m_bInPage = false;
+  bool m_bBufSpecified = false;
+  int32_t m_PauseStep = 10;
+  FXCODEC_STATUS m_ProcessingStatus = FXCODEC_STATUS_FRAME_READY;
   std::vector<JBig2ArithCtx> m_gbContext;
   std::unique_ptr<CJBig2_ArithDecoder> m_pArithDecoder;
   std::unique_ptr<CJBig2_GRDProc> m_pGRD;
   std::unique_ptr<CJBig2_Segment> m_pSegment;
-  FX_SAFE_UINT32 m_dwOffset;
+  FX_SAFE_UINT32 m_dwOffset = 0;
   JBig2RegionInfo m_ri;
   std::list<CJBig2_CachePair>* const m_pSymbolDictCache;
-  bool m_bIsGlobal;
 };
 
 #endif  // CORE_FXCODEC_JBIG2_JBIG2_CONTEXT_H_