Add more resource params to CPDF_PageObjectHolder ctor.

This opens up the possibility of initializing some members via the ctor.
Do so from CPDF_Form, and add a comment to explain why it cannot be done
from CPDF_Page.

Along the way, move a ChooseResourcesDict() helper into CPDF_Form and
use it there.

Change-Id: I8a53bcfb0ea06316ef1e3237f42f02a32046b757
Reviewed-on: https://pdfium-review.googlesource.com/c/47634
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/page/cpdf_form.cpp b/core/fpdfapi/page/cpdf_form.cpp
index c7f2cd9..16ec824 100644
--- a/core/fpdfapi/page/cpdf_form.cpp
+++ b/core/fpdfapi/page/cpdf_form.cpp
@@ -13,6 +13,16 @@
 #include "core/fpdfapi/parser/cpdf_stream.h"
 #include "third_party/base/ptr_util.h"
 
+// static
+CPDF_Dictionary* CPDF_Form::ChooseResourcesDict(
+    CPDF_Dictionary* pResources,
+    CPDF_Dictionary* pParentResources,
+    CPDF_Dictionary* pPageResources) {
+  if (pResources)
+    return pResources;
+  return pParentResources ? pParentResources : pPageResources;
+}
+
 CPDF_Form::CPDF_Form(CPDF_Document* pDoc,
                      CPDF_Dictionary* pPageResources,
                      CPDF_Stream* pFormStream)
@@ -22,14 +32,14 @@
                      CPDF_Dictionary* pPageResources,
                      CPDF_Stream* pFormStream,
                      CPDF_Dictionary* pParentResources)
-    : CPDF_PageObjectHolder(pDoc, pFormStream->GetDict()),
+    : CPDF_PageObjectHolder(
+          pDoc,
+          pFormStream->GetDict(),
+          pPageResources,
+          ChooseResourcesDict(pFormStream->GetDict()->GetDictFor("Resources"),
+                              pParentResources,
+                              pPageResources)),
       m_pFormStream(pFormStream) {
-  m_pResources = GetDict()->GetDictFor("Resources");
-  m_pPageResources = pPageResources;
-  if (!m_pResources)
-    m_pResources = pParentResources;
-  if (!m_pResources)
-    m_pResources = pPageResources;
   LoadTransInfo();
 }
 
diff --git a/core/fpdfapi/page/cpdf_form.h b/core/fpdfapi/page/cpdf_form.h
index 0c51547..8d98d6d 100644
--- a/core/fpdfapi/page/cpdf_form.h
+++ b/core/fpdfapi/page/cpdf_form.h
@@ -12,15 +12,20 @@
 
 #include "core/fpdfapi/page/cpdf_pageobjectholder.h"
 
-class CPDF_Document;
-class CPDF_Dictionary;
-class CPDF_Stream;
-class CPDF_AllStates;
 class CFX_Matrix;
+class CPDF_AllStates;
+class CPDF_Dictionary;
+class CPDF_Document;
+class CPDF_Stream;
 class CPDF_Type3Char;
 
 class CPDF_Form final : public CPDF_PageObjectHolder {
  public:
+  // Helper method to choose the first non-null resources dictionary.
+  static CPDF_Dictionary* ChooseResourcesDict(CPDF_Dictionary* pResources,
+                                              CPDF_Dictionary* pParentResources,
+                                              CPDF_Dictionary* pPageResources);
+
   CPDF_Form(CPDF_Document* pDocument,
             CPDF_Dictionary* pPageResources,
             CPDF_Stream* pFormStream);
diff --git a/core/fpdfapi/page/cpdf_page.cpp b/core/fpdfapi/page/cpdf_page.cpp
index de44367..30e23eb 100644
--- a/core/fpdfapi/page/cpdf_page.cpp
+++ b/core/fpdfapi/page/cpdf_page.cpp
@@ -23,13 +23,16 @@
 CPDF_Page::CPDF_Page(CPDF_Document* pDocument,
                      CPDF_Dictionary* pPageDict,
                      bool bPageCache)
-    : CPDF_PageObjectHolder(pDocument, pPageDict),
+    : CPDF_PageObjectHolder(pDocument, pPageDict, nullptr, nullptr),
       m_PageSize(100, 100),
       m_pPDFDocument(pDocument) {
   ASSERT(pPageDict);
   if (bPageCache)
     m_pPageRender = pdfium::MakeUnique<CPDF_PageRenderCache>(this);
 
+  // Cannot initialize |m_pResources| and |m_pPageResources| via the
+  // CPDF_PageObjectHolder ctor because GetPageAttr() requires
+  // CPDF_PageObjectHolder to finish initializing first.
   CPDF_Object* pPageAttr = GetPageAttr(pdfium::page_object::kResources);
   m_pResources = pPageAttr ? pPageAttr->GetDict() : nullptr;
   m_pPageResources = m_pResources;
diff --git a/core/fpdfapi/page/cpdf_pageobjectholder.cpp b/core/fpdfapi/page/cpdf_pageobjectholder.cpp
index c51ab17..789e596 100644
--- a/core/fpdfapi/page/cpdf_pageobjectholder.cpp
+++ b/core/fpdfapi/page/cpdf_pageobjectholder.cpp
@@ -33,13 +33,18 @@
 }
 
 CPDF_PageObjectHolder::CPDF_PageObjectHolder(CPDF_Document* pDoc,
-                                             CPDF_Dictionary* pDict)
-    : m_pDict(pDict), m_pDocument(pDoc) {
+                                             CPDF_Dictionary* pDict,
+                                             CPDF_Dictionary* pPageResources,
+                                             CPDF_Dictionary* pResources)
+    : m_pPageResources(pPageResources),
+      m_pResources(pResources),
+      m_pDict(pDict),
+      m_pDocument(pDoc) {
   // TODO(thestig): Check if |m_pDict| is never a nullptr and simplify
   // callers that checks for that.
 }
 
-CPDF_PageObjectHolder::~CPDF_PageObjectHolder() {}
+CPDF_PageObjectHolder::~CPDF_PageObjectHolder() = default;
 
 bool CPDF_PageObjectHolder::IsPage() const {
   return false;
diff --git a/core/fpdfapi/page/cpdf_pageobjectholder.h b/core/fpdfapi/page/cpdf_pageobjectholder.h
index 5949329..3c17a3a 100644
--- a/core/fpdfapi/page/cpdf_pageobjectholder.h
+++ b/core/fpdfapi/page/cpdf_pageobjectholder.h
@@ -47,7 +47,10 @@
  public:
   enum class ParseState : uint8_t { kNotParsed, kParsing, kParsed };
 
-  CPDF_PageObjectHolder(CPDF_Document* pDoc, CPDF_Dictionary* pDict);
+  CPDF_PageObjectHolder(CPDF_Document* pDoc,
+                        CPDF_Dictionary* pDict,
+                        CPDF_Dictionary* pPageResources,
+                        CPDF_Dictionary* pResources);
   virtual ~CPDF_PageObjectHolder();
 
   virtual bool IsPage() const;
diff --git a/core/fpdfapi/page/cpdf_streamcontentparser.cpp b/core/fpdfapi/page/cpdf_streamcontentparser.cpp
index e703e7b..a714219 100644
--- a/core/fpdfapi/page/cpdf_streamcontentparser.cpp
+++ b/core/fpdfapi/page/cpdf_streamcontentparser.cpp
@@ -239,14 +239,6 @@
   }
 }
 
-CPDF_Dictionary* ChooseResourcesDict(CPDF_Dictionary* pResources,
-                                     CPDF_Dictionary* pParentResources,
-                                     CPDF_Dictionary* pPageResources) {
-  if (pResources)
-    return pResources;
-  return pParentResources ? pParentResources : pPageResources;
-}
-
 }  // namespace
 
 CPDF_StreamContentParser::CPDF_StreamContentParser(
@@ -262,8 +254,9 @@
     : m_pDocument(pDocument),
       m_pPageResources(pPageResources),
       m_pParentResources(pParentResources),
-      m_pResources(
-          ChooseResourcesDict(pResources, pParentResources, pPageResources)),
+      m_pResources(CPDF_Form::ChooseResourcesDict(pResources,
+                                                  pParentResources,
+                                                  pPageResources)),
       m_pObjectHolder(pObjHolder),
       m_ParsedSet(parsedSet),
       m_BBox(rcBBox),