Move ownership of XML document up to CPDFXFA_Context.

Allows for its lifetime to be managed with other objects that
refer to it.

Change-Id: I1eb8f44096f72585b453a2d37f1a1df145e8caea
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/71911
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/fpdfsdk/fpdfxfa/cpdfxfa_context.cpp b/fpdfsdk/fpdfxfa/cpdfxfa_context.cpp
index 8efac6f..61bea40 100644
--- a/fpdfsdk/fpdfxfa/cpdfxfa_context.cpp
+++ b/fpdfsdk/fpdfxfa/cpdfxfa_context.cpp
@@ -14,6 +14,8 @@
 #include "core/fpdfapi/parser/cpdf_document.h"
 #include "core/fpdfapi/parser/cpdf_seekablemultistream.h"
 #include "core/fxcrt/fx_memory_wrappers.h"
+#include "core/fxcrt/xml/cfx_xmldocument.h"
+#include "core/fxcrt/xml/cfx_xmlparser.h"
 #include "fpdfsdk/cpdfsdk_formfillenvironment.h"
 #include "fpdfsdk/cpdfsdk_pageview.h"
 #include "fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.h"
@@ -123,9 +125,16 @@
     return false;
   }
 
+  CFX_XMLParser parser(stream);
+  m_pXML = parser.Parse();
+  if (!m_pXML) {
+    FXSYS_SetLastError(FPDF_ERR_XFALOAD);
+    return false;
+  }
+
   m_pXFADoc =
       CXFA_FFDoc::CreateAndOpen(m_pXFAApp.get(), m_pDocEnv.get(),
-                                m_pPDFDoc.Get(), m_pGCHeap.get(), stream);
+                                m_pPDFDoc.Get(), m_pGCHeap.get(), m_pXML.get());
 
   if (!m_pXFADoc) {
     FXSYS_SetLastError(FPDF_ERR_XFALOAD);
diff --git a/fpdfsdk/fpdfxfa/cpdfxfa_context.h b/fpdfsdk/fpdfxfa/cpdfxfa_context.h
index 438564f..762e0e1 100644
--- a/fpdfsdk/fpdfxfa/cpdfxfa_context.h
+++ b/fpdfsdk/fpdfxfa/cpdfxfa_context.h
@@ -20,6 +20,7 @@
 #include "fxjs/gc/heap.h"
 #include "xfa/fxfa/cxfa_ffdoc.h"
 
+class CFX_XMLDocument;
 class CJS_Runtime;
 class CPDFXFA_DocEnvironment;
 
@@ -37,6 +38,7 @@
   ~CPDFXFA_Context() override;
 
   bool LoadXFADoc();
+  CFX_XMLDocument* GetXMLDoc() { return m_pXML.get(); }
   CXFA_FFDoc* GetXFADoc() { return m_pXFADoc.get(); }
   CXFA_FFDocView* GetXFADocView() const { return m_pXFADocView.Get(); }
   cppgc::Heap* GetGCHeap() { return m_pGCHeap.get(); }
@@ -115,6 +117,7 @@
 
   // The order in which the following members are destroyed is critical.
   UnownedPtr<CPDF_Document> const m_pPDFDoc;
+  std::unique_ptr<CFX_XMLDocument> m_pXML;
   FXGCScopedHeap m_pGCHeap;
   ObservedPtr<CPDFSDK_FormFillEnvironment> m_pFormFillEnv;
   std::unique_ptr<CXFA_FFApp> const m_pXFAApp;
diff --git a/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp b/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp
index 6f26acb..5e7df9a 100644
--- a/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp
+++ b/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp
@@ -603,6 +603,10 @@
   return pFormFillEnv ? pFormFillEnv->GetIJSRuntime() : nullptr;
 }
 
+CFX_XMLDocument* CPDFXFA_DocEnvironment::GetXMLDoc() const {
+  return m_pContext->GetXMLDoc();
+}
+
 RetainPtr<IFX_SeekableReadStream> CPDFXFA_DocEnvironment::OpenLinkedFile(
     CXFA_FFDoc* hDoc,
     const WideString& wsLink) {
diff --git a/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.h b/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.h
index ebb86c4..76224f5 100644
--- a/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.h
+++ b/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.h
@@ -12,6 +12,7 @@
 #include "public/fpdfview.h"
 #include "xfa/fxfa/fxfa.h"
 
+class CFX_XMLDocument;
 class CPDFXFA_Context;
 class IJS_Runtime;
 
@@ -55,6 +56,7 @@
              uint32_t dwOptions) override;
   FX_ARGB GetHighlightColor(CXFA_FFDoc* hDoc) override;
   IJS_Runtime* GetIJSRuntime(CXFA_FFDoc* hDoc) const override;
+  CFX_XMLDocument* GetXMLDoc() const override;
   RetainPtr<IFX_SeekableReadStream> OpenLinkedFile(
       CXFA_FFDoc* hDoc,
       const WideString& wsLink) override;
diff --git a/xfa/fxfa/cxfa_ffdoc.cpp b/xfa/fxfa/cxfa_ffdoc.cpp
index 6bb8536..41cfe36 100644
--- a/xfa/fxfa/cxfa_ffdoc.cpp
+++ b/xfa/fxfa/cxfa_ffdoc.cpp
@@ -57,7 +57,7 @@
     IXFA_DocEnvironment* pDocEnvironment,
     CPDF_Document* pPDFDoc,
     cppgc::Heap* pGCHeap,
-    const RetainPtr<IFX_SeekableStream>& stream) {
+    CFX_XMLDocument* pXML) {
   ASSERT(pApp);
   ASSERT(pDocEnvironment);
   ASSERT(pPDFDoc);
@@ -65,7 +65,7 @@
   // Use WrapUnique() to keep constructor private.
   auto result = pdfium::WrapUnique(
       new CXFA_FFDoc(pApp, pDocEnvironment, pPDFDoc, pGCHeap));
-  if (!result->OpenDoc(stream))
+  if (!result->OpenDoc(pXML))
     return nullptr;
 
   return result;
@@ -93,21 +93,18 @@
     m_pDocument->ClearLayoutData();
 
   m_pDocument.reset();
-  m_pXMLDoc.reset();
   m_pNotify.reset();
   m_pPDFFontMgr.reset();
   m_HashToDibDpiMap.clear();
   m_pApp->ClearEventTargets();
 }
 
-bool CXFA_FFDoc::ParseDoc(const RetainPtr<IFX_SeekableStream>& stream) {
-  CFX_XMLParser xml_parser(stream);
-  m_pXMLDoc = xml_parser.Parse();
-  if (!m_pXMLDoc)
+bool CXFA_FFDoc::BuildDoc(CFX_XMLDocument* pXML) {
+  if (!pXML)
     return false;
 
   CXFA_DocumentBuilder builder(m_pDocument.get());
-  if (!builder.BuildDocument(m_pXMLDoc.get(), XFA_PacketType::Xdp))
+  if (!builder.BuildDocument(pXML, XFA_PacketType::Xdp))
     return false;
 
   m_pDocument->SetRoot(builder.GetRootNode());
@@ -130,8 +127,8 @@
   return m_DocView.get();
 }
 
-bool CXFA_FFDoc::OpenDoc(const RetainPtr<IFX_SeekableStream>& stream) {
-  if (!ParseDoc(stream))
+bool CXFA_FFDoc::OpenDoc(CFX_XMLDocument* pXML) {
+  if (!BuildDoc(pXML))
     return false;
 
   CFGAS_FontMgr* mgr = GetApp()->GetFDEFontMgr();
diff --git a/xfa/fxfa/cxfa_ffdoc.h b/xfa/fxfa/cxfa_ffdoc.h
index 461ffaa..4d7618d 100644
--- a/xfa/fxfa/cxfa_ffdoc.h
+++ b/xfa/fxfa/cxfa_ffdoc.h
@@ -50,7 +50,7 @@
       IXFA_DocEnvironment* pDocEnvironment,
       CPDF_Document* pPDFDoc,
       cppgc::Heap* pGCHeap,
-      const RetainPtr<IFX_SeekableStream>& stream);
+      CFX_XMLDocument* pXML);
 
   ~CXFA_FFDoc();
 
@@ -59,10 +59,11 @@
   }
   FormType GetFormType() const { return m_FormType; }
   cppgc::Heap* GetHeap() const { return m_pHeap.Get(); }
-  CFX_XMLDocument* GetXMLDocument() const { return m_pXMLDoc.get(); }
+  CFX_XMLDocument* GetXMLDocument() const {
+    return m_pDocEnvironment->GetXMLDoc();
+  }
 
   CXFA_FFDocView* CreateDocView();
-
   CXFA_Document* GetXFADoc() const { return m_pDocument.get(); }
   CXFA_FFApp* GetApp() const { return m_pApp.Get(); }
   CPDF_Document* GetPDFDoc() const { return m_pPDFDoc.Get(); }
@@ -81,14 +82,14 @@
              IXFA_DocEnvironment* pDocEnvironment,
              CPDF_Document* pPDFDoc,
              cppgc::Heap* pHeap);
-  bool OpenDoc(const RetainPtr<IFX_SeekableStream>& stream);
-  bool ParseDoc(const RetainPtr<IFX_SeekableStream>& stream);
+  bool OpenDoc(CFX_XMLDocument* pXML);
+  bool BuildDoc(CFX_XMLDocument* pXML);
 
   UnownedPtr<IXFA_DocEnvironment> const m_pDocEnvironment;
   UnownedPtr<CXFA_FFApp> const m_pApp;
   UnownedPtr<CPDF_Document> const m_pPDFDoc;
   UnownedPtr<cppgc::Heap> const m_pHeap;
-  std::unique_ptr<CFX_XMLDocument> m_pXMLDoc;
+  UnownedPtr<CFX_XMLDocument> m_pXMLDoc;
   std::unique_ptr<CXFA_FFNotify> m_pNotify;
   std::unique_ptr<CXFA_Document> m_pDocument;
   std::unique_ptr<CXFA_FFDocView> m_DocView;
diff --git a/xfa/fxfa/fxfa.h b/xfa/fxfa/fxfa.h
index 2028cd3..f7bb32b 100644
--- a/xfa/fxfa/fxfa.h
+++ b/xfa/fxfa/fxfa.h
@@ -15,6 +15,7 @@
 #include "core/fxge/fx_dib.h"
 #include "xfa/fxfa/fxfa_basic.h"
 
+class CFX_XMLDocument;
 class CXFA_FFDoc;
 class CXFA_FFPageView;
 class CXFA_FFWidget;
@@ -237,6 +238,7 @@
                      uint32_t dwOptions) = 0;
   virtual FX_ARGB GetHighlightColor(CXFA_FFDoc* hDoc) = 0;
   virtual IJS_Runtime* GetIJSRuntime(CXFA_FFDoc* hDoc) const = 0;
+  virtual CFX_XMLDocument* GetXMLDoc() const = 0;
   virtual RetainPtr<IFX_SeekableReadStream> OpenLinkedFile(
       CXFA_FFDoc* hDoc,
       const WideString& wsLink) = 0;