Add CPDF_Form::RecursionState struct

This struct currently contains only one member. Change CPDF_Form and
related classes to pass this struct around, instead of passing its
member directly. Then future changes can pass more state around without
having to add more parameters all over the place.

Change-Id: Ie8da775a42ab18b2477877662cc23a452f09bef1
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/108332
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/page/cpdf_contentparser.cpp b/core/fpdfapi/page/cpdf_contentparser.cpp
index 5ef9d80..d645297 100644
--- a/core/fpdfapi/page/cpdf_contentparser.cpp
+++ b/core/fpdfapi/page/cpdf_contentparser.cpp
@@ -56,12 +56,13 @@
   HandlePageContentFailure();
 }
 
-CPDF_ContentParser::CPDF_ContentParser(RetainPtr<const CPDF_Stream> pStream,
-                                       CPDF_PageObjectHolder* pPageObjectHolder,
-                                       const CPDF_AllStates* pGraphicStates,
-                                       const CFX_Matrix* pParentMatrix,
-                                       CPDF_Type3Char* pType3Char,
-                                       std::set<const uint8_t*>* pParsedSet)
+CPDF_ContentParser::CPDF_ContentParser(
+    RetainPtr<const CPDF_Stream> pStream,
+    CPDF_PageObjectHolder* pPageObjectHolder,
+    const CPDF_AllStates* pGraphicStates,
+    const CFX_Matrix* pParentMatrix,
+    CPDF_Type3Char* pType3Char,
+    CPDF_Form::RecursionState* recursion_state)
     : m_CurrentStage(Stage::kParse),
       m_pPageObjectHolder(pPageObjectHolder),
       m_pType3Char(pType3Char) {
@@ -95,7 +96,7 @@
       m_pPageObjectHolder->GetMutablePageResources(),
       m_pPageObjectHolder->GetMutableResources(), pParentMatrix,
       m_pPageObjectHolder, std::move(pResources), form_bbox, pGraphicStates,
-      pParsedSet);
+      recursion_state);
   m_pParser->GetCurStates()->m_CTM = form_matrix;
   m_pParser->GetCurStates()->m_ParentMatrix = form_matrix;
   if (ClipPath.HasRef()) {
@@ -197,12 +198,12 @@
 
 CPDF_ContentParser::Stage CPDF_ContentParser::Parse() {
   if (!m_pParser) {
-    m_ParsedSet.clear();
+    m_RecursionState.parsed_set.clear();
     m_pParser = std::make_unique<CPDF_StreamContentParser>(
         m_pPageObjectHolder->GetDocument(),
         m_pPageObjectHolder->GetMutablePageResources(), nullptr, nullptr,
         m_pPageObjectHolder, m_pPageObjectHolder->GetMutableResources(),
-        m_pPageObjectHolder->GetBBox(), nullptr, &m_ParsedSet);
+        m_pPageObjectHolder->GetBBox(), nullptr, &m_RecursionState);
     m_pParser->GetCurStates()->m_ColorState.SetDefault();
   }
   if (m_CurrentOffset >= GetData().size())
diff --git a/core/fpdfapi/page/cpdf_contentparser.h b/core/fpdfapi/page/cpdf_contentparser.h
index 090c624..e2660e2 100644
--- a/core/fpdfapi/page/cpdf_contentparser.h
+++ b/core/fpdfapi/page/cpdf_contentparser.h
@@ -10,9 +10,9 @@
 #include <stdint.h>
 
 #include <memory>
-#include <set>
 #include <vector>
 
+#include "core/fpdfapi/page/cpdf_form.h"
 #include "core/fpdfapi/page/cpdf_streamcontentparser.h"
 #include "core/fxcrt/fixed_try_alloc_zeroed_data_vector.h"
 #include "core/fxcrt/retain_ptr.h"
@@ -36,7 +36,7 @@
                      const CPDF_AllStates* pGraphicStates,
                      const CFX_Matrix* pParentMatrix,
                      CPDF_Type3Char* pType3Char,
-                     std::set<const uint8_t*>* pParsedSet);
+                     CPDF_Form::RecursionState* recursion_state);
   ~CPDF_ContentParser();
 
   const CPDF_AllStates* GetCurStates() const {
@@ -80,9 +80,10 @@
       m_Data;
   uint32_t m_nStreams = 0;
   uint32_t m_CurrentOffset = 0;
-  std::set<const uint8_t*> m_ParsedSet;  // Only used when parsing pages.
+  // Only used when parsing pages.
+  CPDF_Form::RecursionState m_RecursionState;
 
-  // Must not outlive |m_pParsedSet|.
+  // Must not outlive |m_RecursionState|.
   std::unique_ptr<CPDF_StreamContentParser> m_pParser;
 };
 
diff --git a/core/fpdfapi/page/cpdf_form.cpp b/core/fpdfapi/page/cpdf_form.cpp
index 90a8650..e66ff0b 100644
--- a/core/fpdfapi/page/cpdf_form.cpp
+++ b/core/fpdfapi/page/cpdf_form.cpp
@@ -18,6 +18,10 @@
 #include "core/fxge/dib/cfx_dibitmap.h"
 #include "third_party/base/check_op.h"
 
+CPDF_Form::RecursionState::RecursionState() = default;
+
+CPDF_Form::RecursionState::~RecursionState() = default;
+
 // static
 CPDF_Dictionary* CPDF_Form::ChooseResourcesDict(
     CPDF_Dictionary* pResources,
@@ -61,8 +65,8 @@
 
 void CPDF_Form::ParseContent(const CPDF_AllStates* pGraphicStates,
                              const CFX_Matrix* pParentMatrix,
-                             std::set<const uint8_t*>* pParsedSet) {
-  ParseContentInternal(pGraphicStates, pParentMatrix, nullptr, pParsedSet);
+                             RecursionState* recursion_state) {
+  ParseContentInternal(pGraphicStates, pParentMatrix, nullptr, recursion_state);
 }
 
 void CPDF_Form::ParseContentForType3Char(CPDF_Type3Char* pType3Char) {
@@ -72,14 +76,14 @@
 void CPDF_Form::ParseContentInternal(const CPDF_AllStates* pGraphicStates,
                                      const CFX_Matrix* pParentMatrix,
                                      CPDF_Type3Char* pType3Char,
-                                     std::set<const uint8_t*>* pParsedSet) {
+                                     RecursionState* recursion_state) {
   if (GetParseState() == ParseState::kParsed)
     return;
 
   if (GetParseState() == ParseState::kNotParsed) {
     StartParse(std::make_unique<CPDF_ContentParser>(
         GetStream(), this, pGraphicStates, pParentMatrix, pType3Char,
-        pParsedSet ? pParsedSet : &m_ParsedSet));
+        recursion_state ? recursion_state : &m_RecursionState));
   }
   DCHECK_EQ(GetParseState(), ParseState::kParsing);
   ContinueParse(nullptr);
diff --git a/core/fpdfapi/page/cpdf_form.h b/core/fpdfapi/page/cpdf_form.h
index 9052b9d..3ced731 100644
--- a/core/fpdfapi/page/cpdf_form.h
+++ b/core/fpdfapi/page/cpdf_form.h
@@ -24,6 +24,13 @@
 class CPDF_Form final : public CPDF_PageObjectHolder,
                         public CPDF_Font::FormIface {
  public:
+  struct RecursionState {
+    RecursionState();
+    ~RecursionState();
+
+    std::set<const uint8_t*> parsed_set;
+  };
+
   // Helper method to choose the first non-null resources dictionary.
   static CPDF_Dictionary* ChooseResourcesDict(CPDF_Dictionary* pResources,
                                               CPDF_Dictionary* pParentResources,
@@ -48,7 +55,7 @@
   void ParseContent();
   void ParseContent(const CPDF_AllStates* pGraphicStates,
                     const CFX_Matrix* pParentMatrix,
-                    std::set<const uint8_t*>* pParsedSet);
+                    RecursionState* recursion_state);
 
   RetainPtr<const CPDF_Stream> GetStream() const;
 
@@ -56,9 +63,9 @@
   void ParseContentInternal(const CPDF_AllStates* pGraphicStates,
                             const CFX_Matrix* pParentMatrix,
                             CPDF_Type3Char* pType3Char,
-                            std::set<const uint8_t*>* pParsedSet);
+                            RecursionState* recursion_state);
 
-  std::set<const uint8_t*> m_ParsedSet;
+  RecursionState m_RecursionState;
   RetainPtr<CPDF_Stream> const m_pFormStream;
 };
 
diff --git a/core/fpdfapi/page/cpdf_streamcontentparser.cpp b/core/fpdfapi/page/cpdf_streamcontentparser.cpp
index 0522cf1..ce3f6fe 100644
--- a/core/fpdfapi/page/cpdf_streamcontentparser.cpp
+++ b/core/fpdfapi/page/cpdf_streamcontentparser.cpp
@@ -250,7 +250,7 @@
     RetainPtr<CPDF_Dictionary> pResources,
     const CFX_FloatRect& rcBBox,
     const CPDF_AllStates* pStates,
-    std::set<const uint8_t*>* pParsedSet)
+    CPDF_Form::RecursionState* recursion_state)
     : m_pDocument(pDocument),
       m_pPageResources(pPageResources),
       m_pParentResources(pParentResources),
@@ -258,7 +258,7 @@
                                                   pParentResources.Get(),
                                                   pPageResources.Get())),
       m_pObjectHolder(pObjHolder),
-      m_ParsedSet(pParsedSet),
+      m_RecursionState(recursion_state),
       m_BBox(rcBBox),
       m_pCurStates(std::make_unique<CPDF_AllStates>()) {
   if (pmtContentToUser)
@@ -772,7 +772,7 @@
   status.m_TextState = m_pCurStates->m_TextState;
   auto form = std::make_unique<CPDF_Form>(
       m_pDocument, m_pPageResources, std::move(pStream), m_pResources.Get());
-  form->ParseContent(&status, nullptr, m_ParsedSet);
+  form->ParseContent(&status, nullptr, m_RecursionState);
 
   CFX_Matrix matrix = m_pCurStates->m_CTM * m_mtContentToUser;
   auto pFormObj = std::make_unique<CPDF_FormObject>(GetCurrentStreamIndex(),
@@ -1535,15 +1535,15 @@
   // Parsing will be done from within |pDataStart|.
   pdfium::span<const uint8_t> pDataStart = pData.subspan(start_offset);
   m_StartParseOffset = start_offset;
-  if (m_ParsedSet->size() > kMaxFormLevel ||
-      pdfium::Contains(*m_ParsedSet, pDataStart.data())) {
+  if (m_RecursionState->parsed_set.size() > kMaxFormLevel ||
+      pdfium::Contains(m_RecursionState->parsed_set, pDataStart.data())) {
     return fxcrt::CollectionSize<uint32_t>(pDataStart);
   }
 
   m_StreamStartOffsets = stream_start_offsets;
 
-  ScopedSetInsertion<const uint8_t*> scopedInsert(m_ParsedSet,
-                                                  pDataStart.data());
+  ScopedSetInsertion<const uint8_t*> scoped_insert(
+      &m_RecursionState->parsed_set, pDataStart.data());
 
   uint32_t init_obj_count = m_pObjectHolder->GetPageObjectCount();
   AutoNuller<std::unique_ptr<CPDF_StreamParser>> auto_clearer(&m_pSyntax);
diff --git a/core/fpdfapi/page/cpdf_streamcontentparser.h b/core/fpdfapi/page/cpdf_streamcontentparser.h
index 276dc72..f11e5c2 100644
--- a/core/fpdfapi/page/cpdf_streamcontentparser.h
+++ b/core/fpdfapi/page/cpdf_streamcontentparser.h
@@ -9,11 +9,11 @@
 
 #include <map>
 #include <memory>
-#include <set>
 #include <stack>
 #include <vector>
 
 #include "core/fpdfapi/page/cpdf_contentmarks.h"
+#include "core/fpdfapi/page/cpdf_form.h"
 #include "core/fxcrt/bytestring.h"
 #include "core/fxcrt/fx_coordinates.h"
 #include "core/fxcrt/fx_number.h"
@@ -49,7 +49,7 @@
                            RetainPtr<CPDF_Dictionary> pResources,
                            const CFX_FloatRect& rcBBox,
                            const CPDF_AllStates* pStates,
-                           std::set<const uint8_t*>* pParsedSet);
+                           CPDF_Form::RecursionState* parse_state);
   ~CPDF_StreamContentParser();
 
   uint32_t Parse(pdfium::span<const uint8_t> pData,
@@ -222,7 +222,7 @@
   RetainPtr<CPDF_Dictionary> const m_pParentResources;
   RetainPtr<CPDF_Dictionary> const m_pResources;
   UnownedPtr<CPDF_PageObjectHolder> const m_pObjectHolder;
-  UnownedPtr<std::set<const uint8_t*>> const m_ParsedSet;
+  UnownedPtr<CPDF_Form::RecursionState> const m_RecursionState;
   CFX_Matrix m_mtContentToUser;
   const CFX_FloatRect m_BBox;
   uint32_t m_ParamStartPos = 0;