From bcf46238b4533a9da91f4fa5d7248bbc85511dbd Mon Sep 17 00:00:00 2001 From: dsinclair Date: Mon, 3 Oct 2016 13:02:27 -0700 Subject: 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 --- fpdfsdk/cpdfsdk_document.cpp | 6 +++++- fpdfsdk/cpdfsdk_pageview.cpp | 3 ++- fpdfsdk/cpdfsdk_pageview.h | 5 +++++ fpdfsdk/fpdfview.cpp | 4 ++++ 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(pPage->GetView()); if (pPageView) { + // We're already destroying the pageview, so bail early. + if (pPageView->IsBeingDestroyed()) + return; + if (pPageView->IsLocked()) { pPageView->TakePageOwnership(); return; -- cgit v1.2.3