Retain widgets across SetFocus() calls in CXFA_FFWidgetHandler.

Bug: chromium:1069789
Change-Id: I65e26b8eb1ef6646ffb29a88d84464cd099fe3cd
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/68696
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/testing/resources/javascript/xfa_specific/bug_1069789.evt b/testing/resources/javascript/xfa_specific/bug_1069789.evt
new file mode 100644
index 0000000..768f6a9
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1069789.evt
@@ -0,0 +1 @@
+mousedown,right,200,200
\ No newline at end of file
diff --git a/testing/resources/javascript/xfa_specific/bug_1069789.in b/testing/resources/javascript/xfa_specific/bug_1069789.in
new file mode 100644
index 0000000..2cb09db
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1069789.in
@@ -0,0 +1,51 @@
+{{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}} <<
+  {{streamlen}}
+>>
+stream
+<template xmlns="http://www.xfa.org/schema/xfa-template/2.6/">
+  <subform name="form1">
+    <pageSet>
+      <pageArea id="Page1" name="Page1">
+        <contentArea h="10.5in" w="8in" x="0.25in" y="0.25in"/>
+        <medium long="11in" short="8.5in" stock="letter"/>
+      </pageArea>
+    </pageSet>
+    <subform h="10.5in" w="8in" name="subform2">
+      <field h="10mm" name="DropDownList1" w="10mm" x="0mm" y="20mm">
+        <ui>
+          <choiceList/>
+        </ui>
+        <items>
+          <text>Single</text>
+        </items>
+      </field>
+      <field h="200mm" name="DropDownList2" w="200mm" x="0mm" y="30mm">
+        <ui>
+          <textEdit/>
+        </ui>
+        <event activity="enter">
+          <script contentType="application/x-javascript">
+            f1 = xfa.resolveNode("xfa.form..DropDownList1");
+            xfa.host.setFocus(f1);
+            xfa.template.remerge();
+            xfa.host.openList(f1);
+          </script>
+        </event>
+      </field>
+    </subform>
+  </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}}
+%%EOF
diff --git a/xfa/fxfa/cxfa_ffwidgethandler.cpp b/xfa/fxfa/cxfa_ffwidgethandler.cpp
index d122917..81bff46 100644
--- a/xfa/fxfa/cxfa_ffwidgethandler.cpp
+++ b/xfa/fxfa/cxfa_ffwidgethandler.cpp
@@ -46,10 +46,14 @@
 bool CXFA_FFWidgetHandler::OnLButtonDown(CXFA_FFWidget* hWidget,
                                          uint32_t dwFlags,
                                          const CFX_PointF& point) {
+  // Prevents destruction of the CXFA_ContentLayoutItem that owns |hWidget|.
+  RetainPtr<CXFA_LayoutItem> retainer(hWidget->GetLayoutItem());
+
   m_pDocView->LockUpdate();
   bool bRet = hWidget->AcceptsFocusOnButtonDown(
       dwFlags, hWidget->Rotate2Normal(point), FWL_MouseCommand::LeftButtonDown);
   if (bRet) {
+    // May re-enter JS.
     if (m_pDocView->SetFocus(hWidget)) {
       m_pDocView->GetDoc()->GetDocEnvironment()->SetFocusWidget(
           m_pDocView->GetDoc(), hWidget);
@@ -94,10 +98,14 @@
 bool CXFA_FFWidgetHandler::OnRButtonDown(CXFA_FFWidget* hWidget,
                                          uint32_t dwFlags,
                                          const CFX_PointF& point) {
+  // Prevents destruction of the CXFA_ContentLayoutItem that owns |hWidget|.
+  RetainPtr<CXFA_LayoutItem> retainer(hWidget->GetLayoutItem());
+
   if (!hWidget->AcceptsFocusOnButtonDown(dwFlags, hWidget->Rotate2Normal(point),
                                          FWL_MouseCommand::RightButtonDown)) {
     return false;
   }
+  // May re-enter JS.
   if (m_pDocView->SetFocus(hWidget)) {
     m_pDocView->GetDoc()->GetDocEnvironment()->SetFocusWidget(
         m_pDocView->GetDoc(), hWidget);