Move some CPDF_Object usage from CXFA_FFDoc up into CPDFXFA_Context.
Ideally, CXFA_FFDoc wouldn't have to poke into CPDF_Object subclasses.
Here we can use the IFX_SeekableStream interface to get some separtion
between these layers.
Change-Id: I79c3be46dfdddee894930a4f035c4c1076e7b671
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/63951
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/fpdfsdk/fpdfxfa/cpdfxfa_context.cpp b/fpdfsdk/fpdfxfa/cpdfxfa_context.cpp
index 7d75948..5f86a90 100644
--- a/fpdfsdk/fpdfxfa/cpdfxfa_context.cpp
+++ b/fpdfsdk/fpdfxfa/cpdfxfa_context.cpp
@@ -9,7 +9,10 @@
#include <algorithm>
#include <utility>
+#include "core/fpdfapi/parser/cpdf_array.h"
+#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/cpdf_document.h"
+#include "core/fpdfapi/parser/cpdf_seekablemultistream.h"
#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
#include "fpdfsdk/cpdfsdk_pageview.h"
#include "fpdfsdk/fpdfxfa/cpdfxfa_page.h"
@@ -44,6 +47,36 @@
type == JSPLATFORM_ALERT_ICON_ASTERISK;
}
+RetainPtr<CPDF_SeekableMultiStream> CreateXFAMultiStream(
+ const CPDF_Document* pPDFDoc) {
+ const CPDF_Dictionary* pRoot = pPDFDoc->GetRoot();
+ if (!pRoot)
+ return nullptr;
+
+ const CPDF_Dictionary* pAcroForm = pRoot->GetDictFor("AcroForm");
+ if (!pAcroForm)
+ return nullptr;
+
+ const CPDF_Object* pElementXFA = pAcroForm->GetDirectObjectFor("XFA");
+ if (!pElementXFA)
+ return nullptr;
+
+ std::vector<const CPDF_Stream*> xfaStreams;
+ if (pElementXFA->IsArray()) {
+ const CPDF_Array* pXFAArray = pElementXFA->AsArray();
+ for (size_t i = 0; i < pXFAArray->size() / 2; i++) {
+ if (const CPDF_Stream* pStream = pXFAArray->GetStreamAt(i * 2 + 1))
+ xfaStreams.push_back(pStream);
+ }
+ } else if (pElementXFA->IsStream()) {
+ xfaStreams.push_back(pElementXFA->AsStream());
+ }
+ if (xfaStreams.empty())
+ return nullptr;
+
+ return pdfium::MakeRetain<CPDF_SeekableMultiStream>(xfaStreams);
+}
+
} // namespace
CPDFXFA_Context::CPDFXFA_Context(CPDF_Document* pPDFDoc)
@@ -100,8 +133,15 @@
bool CPDFXFA_Context::LoadXFADoc() {
m_nLoadStatus = FXFA_LOADSTATUS_LOADING;
m_XFAPageList.clear();
- m_pXFADoc =
- CXFA_FFDoc::CreateAndOpen(m_pXFAApp.get(), &m_DocEnv, m_pPDFDoc.Get());
+
+ auto stream = CreateXFAMultiStream(m_pPDFDoc.Get());
+ if (!stream) {
+ FXSYS_SetLastError(FPDF_ERR_XFALOAD);
+ return false;
+ }
+
+ m_pXFADoc = CXFA_FFDoc::CreateAndOpen(m_pXFAApp.get(), &m_DocEnv,
+ m_pPDFDoc.Get(), stream);
if (!m_pXFADoc) {
FXSYS_SetLastError(FPDF_ERR_XFALOAD);
return false;
diff --git a/xfa/fxfa/cxfa_ffdoc.cpp b/xfa/fxfa/cxfa_ffdoc.cpp
index 0196e5e..ac4b35f 100644
--- a/xfa/fxfa/cxfa_ffdoc.cpp
+++ b/xfa/fxfa/cxfa_ffdoc.cpp
@@ -10,10 +10,8 @@
#include <memory>
#include <vector>
-#include "core/fpdfapi/parser/cpdf_array.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/cpdf_document.h"
-#include "core/fpdfapi/parser/cpdf_seekablemultistream.h"
#include "core/fpdfapi/parser/cpdf_stream.h"
#include "core/fpdfapi/parser/cpdf_stream_acc.h"
#include "core/fpdfdoc/cpdf_nametree.h"
@@ -56,27 +54,16 @@
std::unique_ptr<CXFA_FFDoc> CXFA_FFDoc::CreateAndOpen(
CXFA_FFApp* pApp,
IXFA_DocEnvironment* pDocEnvironment,
- CPDF_Document* pPDFDoc) {
+ CPDF_Document* pPDFDoc,
+ const RetainPtr<IFX_SeekableStream>& stream) {
ASSERT(pApp);
ASSERT(pDocEnvironment);
ASSERT(pPDFDoc);
- const CPDF_Dictionary* pRoot = pPDFDoc->GetRoot();
- if (!pRoot)
- return nullptr;
-
- const CPDF_Dictionary* pAcroForm = pRoot->GetDictFor("AcroForm");
- if (!pAcroForm)
- return nullptr;
-
- const CPDF_Object* pElementXFA = pAcroForm->GetDirectObjectFor("XFA");
- if (!pElementXFA)
- return nullptr;
-
// Use WrapUnique() to keep constructor private.
auto result =
pdfium::WrapUnique(new CXFA_FFDoc(pApp, pDocEnvironment, pPDFDoc));
- if (!result->OpenDoc(pElementXFA))
+ if (!result->OpenDoc(stream))
return nullptr;
return result;
@@ -109,22 +96,7 @@
m_pApp->ClearEventTargets();
}
-bool CXFA_FFDoc::ParseDoc(const CPDF_Object* pElementXFA) {
- std::vector<const CPDF_Stream*> xfaStreams;
- if (pElementXFA->IsArray()) {
- const CPDF_Array* pXFAArray = pElementXFA->AsArray();
- for (size_t i = 0; i < pXFAArray->size() / 2; i++) {
- if (const CPDF_Stream* pStream = pXFAArray->GetStreamAt(i * 2 + 1))
- xfaStreams.push_back(pStream);
- }
- } else if (pElementXFA->IsStream()) {
- xfaStreams.push_back(pElementXFA->AsStream());
- }
- if (xfaStreams.empty())
- return false;
-
- auto stream = pdfium::MakeRetain<CPDF_SeekableMultiStream>(xfaStreams);
-
+bool CXFA_FFDoc::ParseDoc(const RetainPtr<IFX_SeekableStream>& stream) {
CXFA_DocumentParser parser(m_pDocument.get());
bool parsed = parser.Parse(stream, XFA_PacketType::Xdp);
@@ -156,8 +128,8 @@
return m_DocView.get();
}
-bool CXFA_FFDoc::OpenDoc(const CPDF_Object* pElementXFA) {
- if (!ParseDoc(pElementXFA))
+bool CXFA_FFDoc::OpenDoc(const RetainPtr<IFX_SeekableStream>& stream) {
+ if (!ParseDoc(stream))
return false;
CFGAS_FontMgr* mgr = GetApp()->GetFDEFontMgr();
diff --git a/xfa/fxfa/cxfa_ffdoc.h b/xfa/fxfa/cxfa_ffdoc.h
index 06b1785..04d98bc 100644
--- a/xfa/fxfa/cxfa_ffdoc.h
+++ b/xfa/fxfa/cxfa_ffdoc.h
@@ -21,7 +21,6 @@
class CFX_DIBitmap;
class CFX_XMLDocument;
class CPDF_Document;
-class CPDF_Object;
class CXFA_FFApp;
class CXFA_FFNotify;
class CXFA_FFDocView;
@@ -45,7 +44,8 @@
static std::unique_ptr<CXFA_FFDoc> CreateAndOpen(
CXFA_FFApp* pApp,
IXFA_DocEnvironment* pDocEnvironment,
- CPDF_Document* pPDFDoc);
+ CPDF_Document* pPDFDoc,
+ const RetainPtr<IFX_SeekableStream>& stream);
~CXFA_FFDoc();
@@ -74,8 +74,8 @@
CXFA_FFDoc(CXFA_FFApp* pApp,
IXFA_DocEnvironment* pDocEnvironment,
CPDF_Document* pPDFDoc);
- bool OpenDoc(const CPDF_Object* pElementXFA);
- bool ParseDoc(const CPDF_Object* pElementXFA);
+ bool OpenDoc(const RetainPtr<IFX_SeekableStream>& stream);
+ bool ParseDoc(const RetainPtr<IFX_SeekableStream>& stream);
UnownedPtr<IXFA_DocEnvironment> const m_pDocEnvironment;
UnownedPtr<CXFA_FFApp> const m_pApp;