Create CXFA_FFDoc via static function.
Rather than a two-step process involving a subsequent OpenDoc(),
use the static creation function pattern when the creation of
an object may fail.
Change-Id: I77ebd5ba2350ef84235ac8d8f52d6a9ab242da97
Reviewed-on: https://pdfium-review.googlesource.com/c/49991
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 a78ad37..4290aa2 100644
--- a/fpdfsdk/fpdfxfa/cpdfxfa_context.cpp
+++ b/fpdfsdk/fpdfxfa/cpdfxfa_context.cpp
@@ -77,7 +77,6 @@
return;
m_pXFADocView = nullptr;
- m_pXFADoc->CloseDoc();
m_pXFADoc.reset();
}
@@ -108,8 +107,8 @@
if (!pApp)
return false;
- m_pXFADoc = pdfium::MakeUnique<CXFA_FFDoc>(pApp, &m_DocEnv);
- if (!m_pXFADoc->OpenDoc(m_pPDFDoc.Get())) {
+ m_pXFADoc = CXFA_FFDoc::CreateAndOpen(pApp, &m_DocEnv, m_pPDFDoc.Get());
+ if (!m_pXFADoc) {
SetLastError(FPDF_ERR_XFALOAD);
return false;
}
diff --git a/xfa/fxfa/cxfa_ffdoc.cpp b/xfa/fxfa/cxfa_ffdoc.cpp
index c2e10f6..b87e440 100644
--- a/xfa/fxfa/cxfa_ffdoc.cpp
+++ b/xfa/fxfa/cxfa_ffdoc.cpp
@@ -49,11 +49,59 @@
FX_IMAGEDIB_AND_DPI::~FX_IMAGEDIB_AND_DPI() = default;
-CXFA_FFDoc::CXFA_FFDoc(CXFA_FFApp* pApp, IXFA_DocEnvironment* pDocEnvironment)
- : m_pDocEnvironment(pDocEnvironment), m_pApp(pApp) {}
+// static
+std::unique_ptr<CXFA_FFDoc> CXFA_FFDoc::CreateAndOpen(
+ CXFA_FFApp* pApp,
+ IXFA_DocEnvironment* pDocEnvironment,
+ CPDF_Document* pPDFDoc) {
+ 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))
+ return nullptr;
+
+ return result;
+}
+
+CXFA_FFDoc::CXFA_FFDoc(CXFA_FFApp* pApp,
+ IXFA_DocEnvironment* pDocEnvironment,
+ CPDF_Document* pPDFDoc)
+ : m_pDocEnvironment(pDocEnvironment),
+ m_pApp(pApp),
+ m_pPDFDoc(pPDFDoc),
+ m_pNotify(pdfium::MakeUnique<CXFA_FFNotify>(this)),
+ m_pDocument(pdfium::MakeUnique<CXFA_Document>(m_pNotify.get())) {}
CXFA_FFDoc::~CXFA_FFDoc() {
- CloseDoc();
+ if (m_DocView) {
+ m_DocView->RunDocClose();
+ m_DocView.reset();
+ }
+ if (m_pDocument)
+ 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 CPDF_Object* pElementXFA) {
@@ -103,31 +151,10 @@
return m_DocView.get();
}
-bool CXFA_FFDoc::OpenDoc(CPDF_Document* pPDFDoc) {
- if (!pPDFDoc)
+bool CXFA_FFDoc::OpenDoc(const CPDF_Object* pElementXFA) {
+ if (!ParseDoc(pElementXFA))
return false;
- const CPDF_Dictionary* pRoot = pPDFDoc->GetRoot();
- if (!pRoot)
- return false;
-
- const CPDF_Dictionary* pAcroForm = pRoot->GetDictFor("AcroForm");
- if (!pAcroForm)
- return false;
-
- const CPDF_Object* pElementXFA = pAcroForm->GetDirectObjectFor("XFA");
- if (!pElementXFA)
- return false;
-
- m_pPDFDoc = pPDFDoc;
-
- m_pNotify = pdfium::MakeUnique<CXFA_FFNotify>(this);
- m_pDocument = pdfium::MakeUnique<CXFA_Document>(m_pNotify.get());
- if (!ParseDoc(pElementXFA)) {
- CloseDoc();
- return false;
- }
-
CFGAS_FontMgr* mgr = GetApp()->GetFDEFontMgr();
if (!mgr)
return false;
@@ -164,28 +191,9 @@
return true;
}
-void CXFA_FFDoc::CloseDoc() {
- if (m_DocView) {
- m_DocView->RunDocClose();
- m_DocView.reset();
- }
- if (m_pDocument)
- m_pDocument->ClearLayoutData();
-
- m_pDocument.reset();
- m_pXMLDoc.reset();
- m_pNotify.reset();
- m_pPDFFontMgr.reset();
- m_HashToDibDpiMap.clear();
- m_pApp->ClearEventTargets();
-}
-
RetainPtr<CFX_DIBitmap> CXFA_FFDoc::GetPDFNamedImage(WideStringView wsName,
int32_t& iImageXDpi,
int32_t& iImageYDpi) {
- if (!m_pPDFDoc)
- return nullptr;
-
uint32_t dwHash = FX_HashCode_GetW(wsName, false);
auto it = m_HashToDibDpiMap.find(dwHash);
if (it != m_HashToDibDpiMap.end()) {
diff --git a/xfa/fxfa/cxfa_ffdoc.h b/xfa/fxfa/cxfa_ffdoc.h
index 73e8d1b..7b7452c 100644
--- a/xfa/fxfa/cxfa_ffdoc.h
+++ b/xfa/fxfa/cxfa_ffdoc.h
@@ -41,7 +41,11 @@
class CXFA_FFDoc {
public:
- CXFA_FFDoc(CXFA_FFApp* pApp, IXFA_DocEnvironment* pDocEnvironment);
+ static std::unique_ptr<CXFA_FFDoc> CreateAndOpen(
+ CXFA_FFApp* pApp,
+ IXFA_DocEnvironment* pDocEnvironment,
+ CPDF_Document* pPDFDoc);
+
~CXFA_FFDoc();
IXFA_DocEnvironment* GetDocEnvironment() const {
@@ -52,9 +56,6 @@
CXFA_FFDocView* CreateDocView();
- bool OpenDoc(CPDF_Document* pPDFDoc);
- void CloseDoc();
-
CXFA_Document* GetXFADoc() const { return m_pDocument.get(); }
CXFA_FFApp* GetApp() const { return m_pApp.Get(); }
CPDF_Document* GetPDFDoc() const { return m_pPDFDoc.Get(); }
@@ -69,11 +70,15 @@
const RetainPtr<IFX_SeekableStream>& pFile);
private:
+ CXFA_FFDoc(CXFA_FFApp* pApp,
+ IXFA_DocEnvironment* pDocEnvironment,
+ CPDF_Document* pPDFDoc);
+ bool OpenDoc(const CPDF_Object* pElementXFA);
bool ParseDoc(const CPDF_Object* pElementXFA);
UnownedPtr<IXFA_DocEnvironment> const m_pDocEnvironment;
UnownedPtr<CXFA_FFApp> const m_pApp;
- UnownedPtr<CPDF_Document> m_pPDFDoc;
+ UnownedPtr<CPDF_Document> const m_pPDFDoc;
std::unique_ptr<CFX_XMLDocument> m_pXMLDoc;
std::unique_ptr<CXFA_FFNotify> m_pNotify;
std::unique_ptr<CXFA_Document> m_pDocument;