Lock page in LoadFXAnnot to prevent unintended page closing

BUG=410326
R=tsepez@chromium.org

Review URL: https://codereview.chromium.org/594403003
diff --git a/fpdfsdk/include/fsdk_mgr.h b/fpdfsdk/include/fsdk_mgr.h
index 95d1a79..a6f990c 100644
--- a/fpdfsdk/include/fsdk_mgr.h
+++ b/fpdfsdk/include/fsdk_mgr.h
@@ -460,15 +460,12 @@
 	CPDF_OCContext *		m_pOccontent;
 	FX_BOOL					m_bChangeMask;
 };
-
 class CPDFSDK_PageView FX_FINAL
 {
 public:
 	CPDFSDK_PageView(CPDFSDK_Document* pSDKDoc,CPDF_Page* page);
 	~CPDFSDK_PageView();
-public:
 	void PageView_OnDraw(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device,CPDF_RenderOptions* pOptions) ;
-public:
 	CPDF_Annot*						GetPDFAnnotAtPoint(FX_FLOAT pageX, FX_FLOAT pageY);
 	CPDFSDK_Annot*					GetFXAnnotAtPoint(FX_FLOAT pageX, FX_FLOAT pageY);
 	CPDF_Annot*						GetPDFWidgetAtPoint(FX_FLOAT pageX, FX_FLOAT pageY);
@@ -489,7 +486,6 @@
 	CPDF_Page*						GetPDFPage(){return m_page;}
 	CPDF_Document*					GetPDFDocument();
 	CPDFSDK_Document*				GetSDKDocument() {return m_pSDKDoc;}	
-public:
 	FX_BOOL					OnLButtonDown(const CPDF_Point & point, FX_UINT nFlag);
 	FX_BOOL					OnLButtonUp(const CPDF_Point & point, FX_UINT nFlag);
 	FX_BOOL					OnChar(int nChar, FX_UINT nFlag);
@@ -499,39 +495,34 @@
 	FX_BOOL					OnMouseMove(const CPDF_Point & point, int nFlag);
 	FX_BOOL					OnMouseWheel(double deltaX, double deltaY,const CPDF_Point& point, int nFlag);
 	FX_BOOL					IsValidAnnot(FX_LPVOID p);
-public:
 	void					GetCurrentMatrix(CPDF_Matrix& matrix) {matrix = m_curMatrix;}
 	void					UpdateRects(CFX_RectArray& rects);
 	void							UpdateView(CPDFSDK_Annot* pAnnot);
 	CFX_PtrArray*					GetAnnotList(){ return &m_fxAnnotArray; }
 
-public:
 	int						GetPageIndex();
 	void							LoadFXAnnots();
-private:
-	CPDF_Matrix m_curMatrix;
 
+        void SetValid(FX_BOOL bValid) {m_bValid = bValid;}
+        FX_BOOL IsValid() {return m_bValid;}
+        void SetLock(FX_BOOL bLocked) {m_bLocked= bLocked;}
+        FX_BOOL IsLocked() {return m_bLocked;}
+        void TakeOverPage() {m_bTakeOverPage = TRUE;}
 private:
 	void PageView_OnHighlightFormFields(CFX_RenderDevice* pDevice, CPDFSDK_Widget* pWidget);
-
-private:
+        CPDF_Matrix m_curMatrix;
 	CPDF_Page* m_page;
 	CPDF_AnnotList* m_pAnnotList;
-
 	//CPDFSDK_Annot* m_pFocusAnnot;
 	CFX_PtrArray  m_fxAnnotArray;
-
 	CPDFSDK_Document* m_pSDKDoc;
-private:
 	CPDFSDK_Widget* m_CaptureWidget;
 	FX_BOOL m_bEnterWidget;
 	FX_BOOL m_bExitWidget;
 	FX_BOOL m_bOnWidget;
-public:
-	void SetValid(FX_BOOL bValid) {m_bValid = bValid;}
-	FX_BOOL IsValid() {return m_bValid;}
-private:
 	FX_BOOL m_bValid;
+        FX_BOOL m_bLocked;
+        FX_BOOL m_bTakeOverPage;
 };
 
 
diff --git a/fpdfsdk/src/fpdfview.cpp b/fpdfsdk/src/fpdfview.cpp
index 49dabe3..bd49862 100644
--- a/fpdfsdk/src/fpdfview.cpp
+++ b/fpdfsdk/src/fpdfview.cpp
@@ -5,6 +5,7 @@
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
 #include "../include/fsdk_define.h"
+#include "../include/fsdk_mgr.h"
 #include "../include/fpdfview.h"
 #include "../include/fsdk_rendercontext.h"
 #include "../include/fpdf_progressive.h"
@@ -591,6 +592,11 @@
 DLLEXPORT void STDCALL FPDF_ClosePage(FPDF_PAGE page)
 {
 	if (!page) return;
+        CPDFSDK_PageView* pPageView = (CPDFSDK_PageView*)(((CPDF_Page*)page))->GetPrivateData((FX_LPVOID)page);
+        if (pPageView && pPageView->IsLocked()) {
+            pPageView->TakeOverPage();
+            return;
+        }
 	delete (CPDF_Page*)page;
 
 }
diff --git a/fpdfsdk/src/fsdk_mgr.cpp b/fpdfsdk/src/fsdk_mgr.cpp
index 52173b4..efb21a7 100644
--- a/fpdfsdk/src/fsdk_mgr.cpp
+++ b/fpdfsdk/src/fsdk_mgr.cpp
@@ -332,7 +332,14 @@
 
 CPDFSDK_Document::~CPDFSDK_Document()
 {
-	m_pageMap.RemoveAll();
+	FX_POSITION pos = m_pageMap.GetStartPosition();
+	while (pos) {
+            CPDF_Page* pPage = NULL;
+            CPDFSDK_PageView* pPageView = NULL;
+            m_pageMap.GetNextAssoc(pos, pPage, pPageView);
+            delete pPageView;
+        }
+        m_pageMap.RemoveAll();
 	if(m_pInterForm)
 	{
 		m_pInterForm->Destroy();
@@ -453,7 +460,7 @@
 void CPDFSDK_Document::ReMovePageView(CPDF_Page* pPDFPage)
 {
 	CPDFSDK_PageView* pPageView = (CPDFSDK_PageView*)m_pageMap.GetValueAt(pPDFPage);
-	if(pPageView)
+	if(pPageView && !pPageView->IsLocked())
 	{
 		delete pPageView;
 		m_pageMap.RemoveKey(pPDFPage);
@@ -608,7 +615,7 @@
 		CPDF_InterForm* pPDFInterForm = pInterForm->GetInterForm();
 		pPDFInterForm->FixPageFields(page);
 	}
-
+        m_page->SetPrivateData((FX_LPVOID)m_page, (FX_LPVOID)this, NULL);
 	m_fxAnnotArray.RemoveAll();
 
 	m_bEnterWidget = FALSE;
@@ -616,12 +623,15 @@
 	m_bOnWidget = FALSE;
 	m_CaptureWidget = NULL;
 	m_bValid = FALSE;
+        m_bLocked = FALSE;
+        m_bTakeOverPage = FALSE;
 }
 
 CPDFSDK_PageView::~CPDFSDK_PageView()
 {
 	CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();	
 	int nAnnotCount = m_fxAnnotArray.GetSize();
+
 	for (int i=0; i<nAnnotCount; i++)
 	{
 		CPDFSDK_Annot* pAnnot = (CPDFSDK_Annot*)m_fxAnnotArray.GetAt(i);
@@ -638,6 +648,10 @@
 		delete m_pAnnotList;
 		m_pAnnotList = NULL;
 	}
+        m_page->RemovePrivateData((FX_LPVOID)m_page);
+        if(m_bTakeOverPage) {
+            delete m_page;
+        }
 }
 
 void CPDFSDK_PageView::PageView_OnDraw(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device,CPDF_RenderOptions* pOptions)
@@ -972,6 +986,7 @@
 	m_pAnnotList = new CPDF_AnnotList(m_page);
 	CPDF_InterForm::EnableUpdateAP(enableAPUpdate);
 	int nCount = m_pAnnotList->Count();
+        SetLock(TRUE);
 	for(int i=0; i<nCount; i++)
 	{
 		CPDF_Annot* pPDFAnnot = m_pAnnotList->GetAt(i);
@@ -981,6 +996,7 @@
 
 		CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = pEnv->GetAnnotHandlerMgr();
 		ASSERT(pAnnotHandlerMgr != NULL);
+
 		if(pAnnotHandlerMgr)
 		{
 			CPDFSDK_Annot* pAnnot = pAnnotHandlerMgr->NewAnnot(pPDFAnnot, this);
@@ -992,6 +1008,7 @@
 		}
 
 	}
+        SetLock(FALSE);
 }
 
 void	CPDFSDK_PageView::UpdateRects(CFX_RectArray& rects)