summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Sinclair <dsinclair@chromium.org>2016-09-13 14:50:22 -0400
committerDan Sinclair <dsinclair@chromium.org>2016-09-13 14:50:22 -0400
commit5f909eefc176feb7c8cf97afe38982025e9238cd (patch)
tree130b91b074b114533986a4e7f1f553938e87d32e
parenta1d2111945acb35cb3403226e68a1920910fa23e (diff)
downloadpdfium-5f909eefc176feb7c8cf97afe38982025e9238cd.tar.xz
[Merge to 54] Fixup CPDFSDK_PageView and CPDF_Page interactions.
There are several issues when CPDFSDK_PageView and CPDF_Page interact, especially around deletion. This Cl fixes up several places where things go wrong working with these objects. BUG=chromium:632709 R=tsepez@chromium.org Review URL: https://codereview.chromium.org/2340523002 . Review-Url: https://codereview.chromium.org/2319663002
-rw-r--r--fpdfsdk/fpdfview.cpp17
-rw-r--r--fpdfsdk/fsdk_mgr.cpp16
-rw-r--r--fpdfsdk/include/fsdk_mgr.h5
-rw-r--r--fpdfsdk/javascript/Field.cpp11
4 files changed, 37 insertions, 12 deletions
diff --git a/fpdfsdk/fpdfview.cpp b/fpdfsdk/fpdfview.cpp
index dee71ac9e2..1c0af1dc10 100644
--- a/fpdfsdk/fpdfview.cpp
+++ b/fpdfsdk/fpdfview.cpp
@@ -673,9 +673,20 @@ DLLEXPORT void STDCALL FPDF_ClosePage(FPDF_PAGE page) {
#else // PDF_ENABLE_XFA
CPDFSDK_PageView* pPageView =
static_cast<CPDFSDK_PageView*>(pPage->GetView());
- if (pPageView && pPageView->IsLocked()) {
- pPageView->TakeOverPage();
- return;
+ if (pPageView) {
+ if (pPageView->IsLocked()) {
+ pPageView->TakePageOwnership();
+ return;
+ }
+
+ bool owned = pPageView->OwnsPage();
+ // This will delete the |pPageView| object. We must cleanup the PageView
+ // first because it will attempt to reset the View on the |pPage| during
+ // destruction.
+ pPageView->GetSDKDocument()->RemovePageView(pPage);
+ // If the page was owned then the pageview will have deleted the page.
+ if (owned)
+ return;
}
delete pPage;
#endif // PDF_ENABLE_XFA
diff --git a/fpdfsdk/fsdk_mgr.cpp b/fpdfsdk/fsdk_mgr.cpp
index 9017e20b32..1011b92e09 100644
--- a/fpdfsdk/fsdk_mgr.cpp
+++ b/fpdfsdk/fsdk_mgr.cpp
@@ -299,7 +299,7 @@ CPDFSDK_PageView* CPDFSDK_Document::GetPageView(int nIndex) {
return nullptr;
auto it = m_pageMap.find(pTempPage);
- return it->second;
+ return it != m_pageMap.end() ? it->second : nullptr;
}
void CPDFSDK_Document::ProcJavascriptFun() {
@@ -482,7 +482,7 @@ CPDFSDK_PageView::CPDFSDK_PageView(CPDFSDK_Document* pSDKDoc,
m_pSDKDoc(pSDKDoc),
m_CaptureWidget(nullptr),
#ifndef PDF_ENABLE_XFA
- m_bTakeOverPage(FALSE),
+ m_bOwnsPage(false),
#endif // PDF_ENABLE_XFA
m_bEnterWidget(FALSE),
m_bExitWidget(FALSE),
@@ -505,6 +505,13 @@ CPDFSDK_PageView::CPDFSDK_PageView(CPDFSDK_Document* pSDKDoc,
}
CPDFSDK_PageView::~CPDFSDK_PageView() {
+#ifndef PDF_ENABLE_XFA
+ // The call to |ReleaseAnnot| can cause the page pointed to by |m_page| to
+ // be freed, which will cause issues if we try to cleanup the pageview pointer
+ // in |m_page|. So, reset the pageview pointer before doing anything else.
+ m_page->SetView(nullptr);
+#endif // PDF_ENABLE_XFA
+
CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = pEnv->GetAnnotHandlerMgr();
for (CPDFSDK_Annot* pAnnot : m_fxAnnotArray)
@@ -512,11 +519,10 @@ CPDFSDK_PageView::~CPDFSDK_PageView() {
m_fxAnnotArray.clear();
m_pAnnotList.reset();
+
#ifndef PDF_ENABLE_XFA
- m_page->SetView(nullptr);
- if (m_bTakeOverPage) {
+ if (m_bOwnsPage)
delete m_page;
- }
#endif // PDF_ENABLE_XFA
}
diff --git a/fpdfsdk/include/fsdk_mgr.h b/fpdfsdk/include/fsdk_mgr.h
index a0adf04823..cf86e38f42 100644
--- a/fpdfsdk/include/fsdk_mgr.h
+++ b/fpdfsdk/include/fsdk_mgr.h
@@ -607,7 +607,8 @@ class CPDFSDK_PageView final : public CPDF_Page::View {
void SetLock(FX_BOOL bLocked) { m_bLocked = bLocked; }
FX_BOOL IsLocked() { return m_bLocked; }
#ifndef PDF_ENABLE_XFA
- void TakeOverPage() { m_bTakeOverPage = TRUE; }
+ bool OwnsPage() const { return m_bOwnsPage; }
+ void TakePageOwnership() { m_bOwnsPage = true; }
#endif // PDF_ENABLE_XFA
private:
@@ -622,7 +623,7 @@ class CPDFSDK_PageView final : public CPDF_Page::View {
CPDFSDK_Annot* m_CaptureWidget;
#else // PDF_ENABLE_XFA
CPDFSDK_Widget* m_CaptureWidget;
- FX_BOOL m_bTakeOverPage;
+ bool m_bOwnsPage;
#endif // PDF_ENABLE_XFA
FX_BOOL m_bEnterWidget;
FX_BOOL m_bExitWidget;
diff --git a/fpdfsdk/javascript/Field.cpp b/fpdfsdk/javascript/Field.cpp
index 5c279d6b53..0a184d8ef1 100644
--- a/fpdfsdk/javascript/Field.cpp
+++ b/fpdfsdk/javascript/Field.cpp
@@ -260,11 +260,12 @@ void Field::UpdateFormField(CPDFSDK_Document* pDocument,
FX_BOOL bChangeMark,
FX_BOOL bResetAP,
FX_BOOL bRefresh) {
- std::vector<CPDFSDK_Widget*> widgets;
CPDFSDK_InterForm* pInterForm = pDocument->GetInterForm();
- pInterForm->GetWidgets(pFormField, &widgets);
if (bResetAP) {
+ std::vector<CPDFSDK_Widget*> widgets;
+ pInterForm->GetWidgets(pFormField, &widgets);
+
int nFieldType = pFormField->GetFieldType();
if (nFieldType == FIELDTYPE_COMBOBOX || nFieldType == FIELDTYPE_TEXTFIELD) {
for (CPDFSDK_Widget* pWidget : widgets) {
@@ -284,6 +285,12 @@ void Field::UpdateFormField(CPDFSDK_Document* pDocument,
}
if (bRefresh) {
+ // Refresh the widget list. The calls in |bResetAP| may have caused widgets
+ // to be removed from the list. We need to call |GetWidgets| again to be
+ // sure none of the widgets have been deleted.
+ std::vector<CPDFSDK_Widget*> widgets;
+ pInterForm->GetWidgets(pFormField, &widgets);
+
for (CPDFSDK_Widget* pWidget : widgets) {
CPDFSDK_Document* pDoc = pWidget->GetInterForm()->GetDocument();
pDoc->UpdateAllViews(nullptr, pWidget);