Avoid directly including xfa/ layer in fpdf_save.cpp.

All these calls should be routed through fpdfsdk/fpdfxfa - that's
what it is there for.

Change-Id: I374e63e34f1045d4d5061acb75831c45d626efd1
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/64350
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/fpdfsdk/fpdf_save.cpp b/fpdfsdk/fpdf_save.cpp
index 2dfd759..78e0e58 100644
--- a/fpdfsdk/fpdf_save.cpp
+++ b/fpdfsdk/fpdf_save.cpp
@@ -29,8 +29,6 @@
 #include "core/fxcrt/cfx_memorystream.h"
 #include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
 #include "public/fpdf_formfill.h"
-#include "xfa/fxfa/cxfa_ffdocview.h"
-#include "xfa/fxfa/parser/cxfa_object.h"
 #endif
 
 #if defined(OS_ANDROID)
@@ -50,10 +48,6 @@
   if (!pContext->ContainsExtensionForm())
     return true;
 
-  CXFA_FFDocView* pXFADocView = pContext->GetXFADocView();
-  if (!pXFADocView)
-    return true;
-
   CPDF_Document* pPDFDocument = pContext->GetPDFDoc();
   if (!pPDFDocument)
     return false;
@@ -117,53 +111,44 @@
   }
   // L"datasets"
   {
-    RetainPtr<IFX_SeekableStream> pDsfileWrite =
+    RetainPtr<IFX_SeekableStream> pFileWrite =
         pdfium::MakeRetain<CFX_MemoryStream>();
-    CXFA_FFDoc* ffdoc = pXFADocView->GetDoc();
-    if (ffdoc->SavePackage(
-            ToNode(ffdoc->GetXFADoc()->GetXFAObject(XFA_HASHCODE_Datasets)),
-            pDsfileWrite) &&
-        pDsfileWrite->GetSize() > 0) {
+    if (pContext->SaveDatasetsPackage(pFileWrite) &&
+        pFileWrite->GetSize() > 0) {
       auto pDataDict = pPDFDocument->New<CPDF_Dictionary>();
       if (iDataSetsIndex != -1) {
         if (pDataSetsStream) {
-          pDataSetsStream->InitStreamFromFile(pDsfileWrite,
-                                              std::move(pDataDict));
+          pDataSetsStream->InitStreamFromFile(pFileWrite, std::move(pDataDict));
         }
       } else {
         CPDF_Stream* pData = pPDFDocument->NewIndirect<CPDF_Stream>();
-        pData->InitStreamFromFile(pDsfileWrite, std::move(pDataDict));
+        pData->InitStreamFromFile(pFileWrite, std::move(pDataDict));
         int iLast = pArray->size() - 2;
         pArray->InsertNewAt<CPDF_String>(iLast, "datasets", false);
         pArray->InsertNewAt<CPDF_Reference>(iLast + 1, pPDFDocument,
                                             pData->GetObjNum());
       }
-      fileList->push_back(std::move(pDsfileWrite));
+      fileList->push_back(std::move(pFileWrite));
     }
   }
   // L"form"
   {
-    RetainPtr<IFX_SeekableStream> pfileWrite =
+    RetainPtr<IFX_SeekableStream> pFileWrite =
         pdfium::MakeRetain<CFX_MemoryStream>();
-
-    CXFA_FFDoc* ffdoc = pXFADocView->GetDoc();
-    if (ffdoc->SavePackage(
-            ToNode(ffdoc->GetXFADoc()->GetXFAObject(XFA_HASHCODE_Form)),
-            pfileWrite) &&
-        pfileWrite->GetSize() > 0) {
+    if (pContext->SaveFormPackage(pFileWrite) && pFileWrite->GetSize() > 0) {
       auto pDataDict = pPDFDocument->New<CPDF_Dictionary>();
       if (iFormIndex != -1) {
         if (pFormStream)
-          pFormStream->InitStreamFromFile(pfileWrite, std::move(pDataDict));
+          pFormStream->InitStreamFromFile(pFileWrite, std::move(pDataDict));
       } else {
         CPDF_Stream* pData = pPDFDocument->NewIndirect<CPDF_Stream>();
-        pData->InitStreamFromFile(pfileWrite, std::move(pDataDict));
+        pData->InitStreamFromFile(pFileWrite, std::move(pDataDict));
         int iLast = pArray->size() - 2;
         pArray->InsertNewAt<CPDF_String>(iLast, "form", false);
         pArray->InsertNewAt<CPDF_Reference>(iLast + 1, pPDFDocument,
                                             pData->GetObjNum());
       }
-      fileList->push_back(std::move(pfileWrite));
+      fileList->push_back(std::move(pFileWrite));
     }
   }
   return true;
diff --git a/fpdfsdk/fpdfxfa/cpdfxfa_context.cpp b/fpdfsdk/fpdfxfa/cpdfxfa_context.cpp
index 5f86a90..7cb4a2c 100644
--- a/fpdfsdk/fpdfxfa/cpdfxfa_context.cpp
+++ b/fpdfsdk/fpdfxfa/cpdfxfa_context.cpp
@@ -357,6 +357,27 @@
   return m_pFormFillEnv ? m_pFormFillEnv->GetTimerHandler() : nullptr;
 }
 
+bool CPDFXFA_Context::SaveDatasetsPackage(
+    const RetainPtr<IFX_SeekableStream>& pStream) {
+  return SavePackage(pStream, XFA_HASHCODE_Datasets);
+}
+
+bool CPDFXFA_Context::SaveFormPackage(
+    const RetainPtr<IFX_SeekableStream>& pStream) {
+  return SavePackage(pStream, XFA_HASHCODE_Form);
+}
+
+bool CPDFXFA_Context::SavePackage(const RetainPtr<IFX_SeekableStream>& pStream,
+                                  XFA_HashCode code) {
+  CXFA_FFDocView* pXFADocView = GetXFADocView();
+  if (!pXFADocView)
+    return false;
+
+  CXFA_FFDoc* ffdoc = pXFADocView->GetDoc();
+  return ffdoc->SavePackage(ToNode(ffdoc->GetXFADoc()->GetXFAObject(code)),
+                            pStream);
+}
+
 void CPDFXFA_Context::SendPostSaveToXFADoc() {
   if (!ContainsExtensionForm())
     return;
diff --git a/fpdfsdk/fpdfxfa/cpdfxfa_context.h b/fpdfsdk/fpdfxfa/cpdfxfa_context.h
index 310b18f..0f6a14b 100644
--- a/fpdfsdk/fpdfxfa/cpdfxfa_context.h
+++ b/fpdfsdk/fpdfxfa/cpdfxfa_context.h
@@ -88,6 +88,8 @@
                      const WideString& wsEncode) override;
   TimerHandlerIface* GetTimerHandler() const override;
 
+  bool SaveDatasetsPackage(const RetainPtr<IFX_SeekableStream>& pStream);
+  bool SaveFormPackage(const RetainPtr<IFX_SeekableStream>& pStream);
   void SendPostSaveToXFADoc();
   void SendPreSaveToXFADoc(
       std::vector<RetainPtr<IFX_SeekableStream>>* fileList);
@@ -107,6 +109,8 @@
   }
 
   CJS_Runtime* GetCJSRuntime() const;
+  bool SavePackage(const RetainPtr<IFX_SeekableStream>& pStream,
+                   XFA_HashCode code);
   void CloseXFADoc();
 
   FormType m_FormType = FormType::kNone;