Make CPDFSDK_Pageview observable across mouse move callbacks

Bug: chromium:1017494
Change-Id: I8a7590be50d11f22e854531903565b2528539005
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/61871
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/page/cpdf_page.h b/core/fpdfapi/page/cpdf_page.h
index 3f64d94..8c4fae3 100644
--- a/core/fpdfapi/page/cpdf_page.h
+++ b/core/fpdfapi/page/cpdf_page.h
@@ -14,8 +14,8 @@
 #include "core/fpdfapi/page/ipdf_page.h"
 #include "core/fxcrt/fx_coordinates.h"
 #include "core/fxcrt/fx_system.h"
+#include "core/fxcrt/observed_ptr.h"
 #include "core/fxcrt/retain_ptr.h"
-#include "core/fxcrt/unowned_ptr.h"
 #include "third_party/base/optional.h"
 
 class CPDF_Dictionary;
@@ -25,7 +25,8 @@
 
 class CPDF_Page final : public IPDF_Page, public CPDF_PageObjectHolder {
  public:
-  class View {};  // Caller implements as desired, empty here due to layering.
+  // Caller implements as desired, empty here due to layering.
+  class View : public Observable {};
 
   // Data for the render layer to attach to this page.
   class RenderContextIface {
@@ -79,7 +80,7 @@
 
   CPDF_Document* GetPDFDocument() const { return m_pPDFDocument.Get(); }
   View* GetView() const { return m_pView.Get(); }
-  void SetView(View* pView) { m_pView = pView; }
+  void SetView(View* pView) { m_pView.Reset(pView); }
   void UpdateDimensions();
 
  private:
@@ -94,7 +95,7 @@
   UnownedPtr<CPDF_Document> m_pPDFDocument;
   std::unique_ptr<RenderCacheIface> m_pRenderCache;
   std::unique_ptr<RenderContextIface> m_pRenderContext;
-  UnownedPtr<View> m_pView;
+  ObservedPtr<View> m_pView;
 };
 
 #endif  // CORE_FPDFAPI_PAGE_CPDF_PAGE_H_
diff --git a/fpdfsdk/cpdfsdk_pageview.cpp b/fpdfsdk/cpdfsdk_pageview.cpp
index 9c7159e..376e542 100644
--- a/fpdfsdk/cpdfsdk_pageview.cpp
+++ b/fpdfsdk/cpdfsdk_pageview.cpp
@@ -370,27 +370,31 @@
 bool CPDFSDK_PageView::OnMouseMove(const CFX_PointF& point, int nFlag) {
   CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr =
       m_pFormFillEnv->GetAnnotHandlerMgr();
+
   ObservedPtr<CPDFSDK_Annot> pFXAnnot(GetFXAnnotAtPoint(point));
+  ObservedPtr<CPDFSDK_PageView> pThis(this);
 
   if (m_bOnWidget && m_pCaptureWidget != pFXAnnot)
     ExitWidget(pAnnotHandlerMgr, true, nFlag);
 
-  if (pFXAnnot) {
-    if (!m_bOnWidget) {
-      EnterWidget(pAnnotHandlerMgr, &pFXAnnot, nFlag);
+  // ExitWidget() may have invalidated objects.
+  if (!pThis || !pFXAnnot)
+    return false;
 
-      // Annot_OnMouseEnter may have invalidated pFXAnnot.
-      if (!pFXAnnot) {
-        ExitWidget(pAnnotHandlerMgr, false, nFlag);
-        return true;
-      }
+  if (!m_bOnWidget) {
+    EnterWidget(pAnnotHandlerMgr, &pFXAnnot, nFlag);
+
+    // EnterWidget() may have invalidated objects.
+    if (!pThis)
+      return false;
+
+    if (!pFXAnnot) {
+      ExitWidget(pAnnotHandlerMgr, false, nFlag);
+      return true;
     }
-
-    pAnnotHandlerMgr->Annot_OnMouseMove(this, &pFXAnnot, nFlag, point);
-    return true;
   }
-
-  return false;
+  pAnnotHandlerMgr->Annot_OnMouseMove(this, &pFXAnnot, nFlag, point);
+  return true;
 }
 
 void CPDFSDK_PageView::EnterWidget(CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr,
diff --git a/testing/resources/javascript/xfa_specific/bug_1017494.evt b/testing/resources/javascript/xfa_specific/bug_1017494.evt
new file mode 100644
index 0000000..bf27458
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1017494.evt
@@ -0,0 +1,3 @@
+mousemove,0,0
+focus,87,0
+charcode,1
diff --git a/testing/resources/javascript/xfa_specific/bug_1017494.in b/testing/resources/javascript/xfa_specific/bug_1017494.in
new file mode 100644
index 0000000..586a6ff
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1017494.in
@@ -0,0 +1,35 @@
+{{header}}
+{{include ../../xfa_catalog_1_0.fragment}}
+{{include ../../xfa_object_2_0.fragment}}
+{{include ../../xfa_preamble_3_0.fragment}}
+{{include ../../xfa_config_4_0.fragment}}
+{{object 5 0}} <<
+  {{streanlen}}
+>>
+stream
+<template xmlns="http://www.xfa.org/schema/xfa-template/3.3/">
+  <subform layout="tb" name="subform2">
+    <field w="100pt" h="420pt" name="Field0"/>
+      <draw name="Field1">
+      <ui>
+        <barcode type="ean8"/>
+      </ui>
+      <value>
+        <text>12ab,.</text>
+      </value>
+    </draw>
+    <pageSet>
+      <pageArea name="PageArea3">
+        <contentArea h="44pt"/>
+      </pageArea>
+    </pageSet>
+  </subform>
+</template>
+endstream
+endobj
+{{include ../../xfa_locale_6_0.fragment}}
+{{include ../../xfa_postamble_7_0.fragment}}
+{{include ../../xfa_pages_8_0.fragment}}
+{{xref}}
+{{trailer}}
+{{startxref}}