summaryrefslogtreecommitdiff
path: root/fpdfsdk
diff options
context:
space:
mode:
authorOliver Chang <ochang@chromium.org>2015-10-30 12:59:29 -0700
committerOliver Chang <ochang@chromium.org>2015-10-30 12:59:29 -0700
commit972b78dbde75ee8434f134da9d364bca926c4a8a (patch)
tree277d8acc5c4a01a03f881187dff099a86ea612a9 /fpdfsdk
parentf71d1e2295bc3d229a20e480c9da9265d2623eff (diff)
downloadpdfium-972b78dbde75ee8434f134da9d364bca926c4a8a.tar.xz
Merge to XFA: Rip out the KillFocusAnnot call from CPDFSDK_PageView's destructor
Previously, blur event actions could potentially touch deleted PageViews as CPDFSDK_Document deletes the PageViews one by one. This also fixes a related issue: CPDFSDK_Document::SetFocusAnnot no longer does anything if the document is being destroyed. Otherwise, it eventually tries to use m_pEnv->GetSDKDocument() at which point has already been set to NULL by FPDFDOC_ExitFormFillEnvironment. TBR=tsepez@chromium.org BUG=512445 Clean merge. Review URL: https://codereview.chromium.org/1414353007 . (cherry picked from commit a548b1d3e2444f256bcbf6c2fa2165798e33ba8d) Review URL: https://codereview.chromium.org/1423343004 .
Diffstat (limited to 'fpdfsdk')
-rw-r--r--fpdfsdk/include/fsdk_mgr.h2
-rw-r--r--fpdfsdk/src/fsdk_mgr.cpp31
2 files changed, 24 insertions, 9 deletions
diff --git a/fpdfsdk/include/fsdk_mgr.h b/fpdfsdk/include/fsdk_mgr.h
index d19c9233d7..97e5863f98 100644
--- a/fpdfsdk/include/fsdk_mgr.h
+++ b/fpdfsdk/include/fsdk_mgr.h
@@ -528,6 +528,7 @@ class CPDFSDK_Document {
CPDFDoc_Environment* m_pEnv;
CPDF_OCContext* m_pOccontent;
FX_BOOL m_bChangeMask;
+ FX_BOOL m_bBeingDestroyed;
};
class CPDFSDK_PageView final {
public:
@@ -548,6 +549,7 @@ class CPDFSDK_PageView final {
FX_BOOL KillFocusAnnot(FX_UINT nFlag = 0) {
return m_pSDKDoc->KillFocusAnnot(nFlag);
}
+ void KillFocusAnnotIfNeeded();
FX_BOOL Annot_HasAppearance(CPDF_Annot* pAnnot);
CPDFSDK_Annot* AddAnnot(CPDF_Dictionary* pDict);
diff --git a/fpdfsdk/src/fsdk_mgr.cpp b/fpdfsdk/src/fsdk_mgr.cpp
index c421673f15..383acbd4a9 100644
--- a/fpdfsdk/src/fsdk_mgr.cpp
+++ b/fpdfsdk/src/fsdk_mgr.cpp
@@ -413,9 +413,16 @@ CPDFSDK_Document::CPDFSDK_Document(CPDFXFA_Document* pDoc,
m_pFocusAnnot(nullptr),
m_pEnv(pEnv),
m_pOccontent(nullptr),
- m_bChangeMask(FALSE) {}
+ m_bChangeMask(FALSE),
+ m_bBeingDestroyed(FALSE) {
+}
CPDFSDK_Document::~CPDFSDK_Document() {
+ m_bBeingDestroyed = TRUE;
+
+ for (auto& it : m_pageMap)
+ it.second->KillFocusAnnotIfNeeded();
+
for (auto& it : m_pageMap)
delete it.second;
m_pageMap.clear();
@@ -514,6 +521,7 @@ void CPDFSDK_Document::ReMovePageView(CPDFXFA_Page* pPDFXFAPage) {
if (pPageView->IsLocked())
return;
+ pPageView->KillFocusAnnotIfNeeded();
delete pPageView;
m_pageMap.erase(it);
}
@@ -546,6 +554,9 @@ CPDFSDK_Annot* CPDFSDK_Document::GetFocusAnnot() {
}
FX_BOOL CPDFSDK_Document::SetFocusAnnot(CPDFSDK_Annot* pAnnot, FX_UINT nFlag) {
+ if (m_bBeingDestroyed)
+ return FALSE;
+
if (m_pFocusAnnot == pAnnot)
return TRUE;
@@ -658,14 +669,6 @@ CPDFSDK_PageView::CPDFSDK_PageView(CPDFSDK_Document* pSDKDoc,
}
CPDFSDK_PageView::~CPDFSDK_PageView() {
- // if there is a focused annot on the page, we should kill the focus first.
- if (CPDFSDK_Annot* focusedAnnot = m_pSDKDoc->GetFocusAnnot()) {
- auto it =
- std::find(m_fxAnnotArray.begin(), m_fxAnnotArray.end(), focusedAnnot);
- if (it != m_fxAnnotArray.end())
- KillFocusAnnot();
- }
-
CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = pEnv->GetAnnotHandlerMgr();
for (CPDFSDK_Annot* pAnnot : m_fxAnnotArray)
@@ -780,6 +783,16 @@ CPDFSDK_Annot* CPDFSDK_PageView::GetFXWidgetAtPoint(FX_FLOAT pageX,
return nullptr;
}
+void CPDFSDK_PageView::KillFocusAnnotIfNeeded() {
+ // if there is a focused annot on the page, we should kill the focus first.
+ if (CPDFSDK_Annot* focusedAnnot = m_pSDKDoc->GetFocusAnnot()) {
+ auto it =
+ std::find(m_fxAnnotArray.begin(), m_fxAnnotArray.end(), focusedAnnot);
+ if (it != m_fxAnnotArray.end())
+ KillFocusAnnot();
+ }
+}
+
FX_BOOL CPDFSDK_PageView::Annot_HasAppearance(CPDF_Annot* pAnnot) {
CPDF_Dictionary* pAnnotDic = pAnnot->GetAnnotDict();
if (pAnnotDic)