summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordsinclair <dsinclair@chromium.org>2016-10-03 13:02:27 -0700
committerCommit bot <commit-bot@chromium.org>2016-10-03 13:02:27 -0700
commitbcf46238b4533a9da91f4fa5d7248bbc85511dbd (patch)
tree755c25e5ffcf6eec6461097e0d4d366bde65a7c8
parentd61f958385be285f3f3897ef3a3f010048608f1c (diff)
downloadpdfium-bcf46238b4533a9da91f4fa5d7248bbc85511dbd.tar.xz
Guard against double deletion of page views.
This CL adds a |IsBeingDestroyed| flag into the CPDFSDK_PageView. We then bail out of the pageview removal code early if the flag is set. BUG=chromium:652103 Review-Url: https://codereview.chromium.org/2384243002
-rw-r--r--fpdfsdk/cpdfsdk_document.cpp6
-rw-r--r--fpdfsdk/cpdfsdk_pageview.cpp3
-rw-r--r--fpdfsdk/cpdfsdk_pageview.h5
-rw-r--r--fpdfsdk/fpdfview.cpp4
4 files changed, 16 insertions, 2 deletions
diff --git a/fpdfsdk/cpdfsdk_document.cpp b/fpdfsdk/cpdfsdk_document.cpp
index ad4516d53c..66851c0ebb 100644
--- a/fpdfsdk/cpdfsdk_document.cpp
+++ b/fpdfsdk/cpdfsdk_document.cpp
@@ -135,9 +135,13 @@ void CPDFSDK_Document::RemovePageView(UnderlyingPageType* pUnderlyingPage) {
return;
CPDFSDK_PageView* pPageView = it->second;
- if (pPageView->IsLocked())
+ if (pPageView->IsLocked() || pPageView->IsBeingDestroyed())
return;
+ // Mark the page view so we do not come into |RemovePageView| a second
+ // time while we're in the process of removing.
+ pPageView->SetBeingDestroyed();
+
// This must happen before we remove |pPageView| from the map because
// |KillFocusAnnotIfNeeded| can call into the |GetPage| method which will
// look for this page view in the map, if it doesn't find it a new one will
diff --git a/fpdfsdk/cpdfsdk_pageview.cpp b/fpdfsdk/cpdfsdk_pageview.cpp
index beba7b68f4..2e7e6c0ad6 100644
--- a/fpdfsdk/cpdfsdk_pageview.cpp
+++ b/fpdfsdk/cpdfsdk_pageview.cpp
@@ -39,7 +39,8 @@ CPDFSDK_PageView::CPDFSDK_PageView(CPDFSDK_Document* pSDKDoc,
m_bExitWidget(FALSE),
m_bOnWidget(FALSE),
m_bValid(FALSE),
- m_bLocked(FALSE) {
+ m_bLocked(FALSE),
+ m_bBeingDestroyed(false) {
CPDFSDK_InterForm* pInterForm = pSDKDoc->GetInterForm();
if (pInterForm) {
CPDF_InterForm* pPDFInterForm = pInterForm->GetInterForm();
diff --git a/fpdfsdk/cpdfsdk_pageview.h b/fpdfsdk/cpdfsdk_pageview.h
index fe40300c23..f837ba5a91 100644
--- a/fpdfsdk/cpdfsdk_pageview.h
+++ b/fpdfsdk/cpdfsdk_pageview.h
@@ -98,6 +98,10 @@ class CPDFSDK_PageView final : public CPDF_Page::View {
void SetLock(FX_BOOL bLocked) { m_bLocked = bLocked; }
FX_BOOL IsLocked() { return m_bLocked; }
+
+ void SetBeingDestroyed() { m_bBeingDestroyed = true; }
+ bool IsBeingDestroyed() const { return m_bBeingDestroyed; }
+
#ifndef PDF_ENABLE_XFA
bool OwnsPage() const { return m_bOwnsPage; }
void TakePageOwnership() { m_bOwnsPage = true; }
@@ -120,6 +124,7 @@ class CPDFSDK_PageView final : public CPDF_Page::View {
FX_BOOL m_bOnWidget;
FX_BOOL m_bValid;
FX_BOOL m_bLocked;
+ bool m_bBeingDestroyed;
};
#endif // FPDFSDK_CPDFSDK_PAGEVIEW_H_
diff --git a/fpdfsdk/fpdfview.cpp b/fpdfsdk/fpdfview.cpp
index 5c5532e024..e48c2e9eb1 100644
--- a/fpdfsdk/fpdfview.cpp
+++ b/fpdfsdk/fpdfview.cpp
@@ -670,6 +670,10 @@ DLLEXPORT void STDCALL FPDF_ClosePage(FPDF_PAGE page) {
CPDFSDK_PageView* pPageView =
static_cast<CPDFSDK_PageView*>(pPage->GetView());
if (pPageView) {
+ // We're already destroying the pageview, so bail early.
+ if (pPageView->IsBeingDestroyed())
+ return;
+
if (pPageView->IsLocked()) {
pPageView->TakePageOwnership();
return;