Retain owning layout items earlier in CXFA_FFField

Safer, even on the paths where we know we short-circuit.

Bug: chromium:1082597
Change-Id: Ie4116dba8bfac54c7a4fcb181fecbd3d7ee1389e
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/69910
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/testing/resources/javascript/xfa_specific/bug_1082597.in b/testing/resources/javascript/xfa_specific/bug_1082597.in
new file mode 100644
index 0000000..91a0ef0
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1082597.in
@@ -0,0 +1,150 @@
+{{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>
+ <subform layout="tb" name="my_doc">
+  <pageSet id="page" relation="orderedOccurrence">
+   <occur initial="1" max="4" min="1"/>
+   <pageArea id="Page1" name="Page1">
+    <occur max="1" min="1"/>
+    <contentArea h="100mm" w="200mm" x="0.25in" y="0.25in"/>
+    <medium long="297mm" short="210mm" stock="a4"/>
+   </pageArea>
+   <pageArea id="Page2" name="Page2">
+    <occur max="1" min="1"/>
+    <contentArea h="100mm" w="200mm" x="0.25in" y="0.25in"/>
+    <medium long="297mm" short="210mm" stock="a4"/>
+   </pageArea>
+  </pageSet>
+  <event activity="docReady" ref="$host">
+   <script contentType="application/x-javascript">
+    xfa.event.emit();
+    var f=xfa.resolveNode("xfa.form.my_doc.page1_form.combox");
+    xfa.record.nodes.append(this);
+    xfa.form.remerge();
+    xfa.host.setFocus(f);
+    app.alert('Done');
+   </script>
+  </event>
+  <subform layout="tb" name="subform_push_button_1">
+   <occur initial="1" max="10" min="0" name="occur_subform_push_button_1"/>
+   <field h="10mm" name="push_button" w="40mm" x="30mm" y="500mm">
+    <ui>
+     <button highlight="push"/>
+    </ui>
+    <caption>
+     <value>
+      <text>Button</text>
+     </value>
+    </caption>
+    <items>
+     <text name="down">Down Text</text>
+     <text name="rollover">Rollover Text</text>
+    </items>
+   </field>
+  </subform>
+  <subform layout="tb" name="subform_checkbutton_group_0">
+   <occur initial="1" max="10" min="0" name="occur_subform_checkbutton_group_0"/>
+   <exclGroup layout="tb" name="checkbutton_group">
+    <field h="10mm" name="checkbutton_check1" w="40mm" x="30mm" y="600mm">
+     <ui>
+      <checkButton shape="round">
+       <border>
+        <edge/>
+       </border>
+      </checkButton>
+     </ui>
+     <items>
+      <integer>1</integer>
+     </items>
+     <value>
+      <text>Select 1</text>
+     </value>
+     <caption placement="left">
+      <value>
+       <text>Option 1</text>
+      </value>
+     </caption>
+     <event activity="ready" ref="$layout">
+      <script contentType="application/x-javascript">
+      </script>
+     </event>
+    </field>
+    <field h="10mm" name="checkbutton_check2" w="40mm" x="30mm" y="600mm">
+     <ui>
+      <checkButton shape="round">
+       <border>
+        <edge/>
+       </border>
+      </checkButton>
+     </ui>
+     <items>
+      <integer>2</integer>
+     </items>
+     <value>
+      <text>Select 2</text>
+     </value>
+     <caption placement="left">
+      <value>
+       <text>Option 2</text>
+      </value>
+     </caption>
+    </field>
+   </exclGroup>
+  </subform>
+  <subform layout="tb" name="page2_form">
+   <occur initial="1" max="3" min="0"/>
+   <field h="10mm" name="textedit" w="40mm" x="20mm" y="20mm">
+    <ui>
+     <textEdit/>
+    </ui>
+    <value>
+     <text>CLGT.</text>
+    </value>
+   </field>
+  </subform>
+  <subform layout="tb" name="page1_form">
+   <occur initial="1" max="3" min="0"/>
+   <field h="10mm" name="combox" w="40mm" x="10mm" y="10mm">
+    <ui>
+     <choiceList open="onEntry">
+      <border>
+       <edge/>
+      </border>
+     </choiceList>
+    </ui>
+    <items save="1">
+     <text>apples</text>
+     <text>bananas</text>
+     <text>pears</text>
+    </items>
+    <value>
+     <text>
+      apples
+     </text>
+    </value>
+    <event activity="enter" name="event__enter">
+     <script contentType="application/x-javascript">
+      xfa.host.setFocus(0);
+      xfa.host.openList(this);
+     </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/testing/resources/javascript/xfa_specific/bug_1082597_expected.txt b/testing/resources/javascript/xfa_specific/bug_1082597_expected.txt
new file mode 100644
index 0000000..3cb772d
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1082597_expected.txt
@@ -0,0 +1,3 @@
+Alert: Done
+Alert: Done
+Alert: Done
diff --git a/xfa/fxfa/cxfa_fffield.cpp b/xfa/fxfa/cxfa_fffield.cpp
index a90b9aa..c4fccca 100644
--- a/xfa/fxfa/cxfa_fffield.cpp
+++ b/xfa/fxfa/cxfa_fffield.cpp
@@ -383,12 +383,12 @@
 }
 
 bool CXFA_FFField::OnMouseEnter() {
-  if (!GetNormalWidget())
-    return false;
-
   // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
   RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
 
+  if (!GetNormalWidget())
+    return false;
+
   SendMessageToFWLWidget(pdfium::MakeUnique<CFWL_MessageMouse>(
       GetNormalWidget(), FWL_MouseCommand::Enter));
 
@@ -396,12 +396,12 @@
 }
 
 bool CXFA_FFField::OnMouseExit() {
-  if (!GetNormalWidget())
-    return false;
-
   // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
   RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
 
+  if (!GetNormalWidget())
+    return false;
+
   SendMessageToFWLWidget(pdfium::MakeUnique<CFWL_MessageMouse>(
       GetNormalWidget(), FWL_MouseCommand::Leave));
 
@@ -440,14 +440,14 @@
 }
 
 bool CXFA_FFField::OnLButtonUp(uint32_t dwFlags, const CFX_PointF& point) {
+  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
+  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
+
   if (!GetNormalWidget())
     return false;
   if (!IsButtonDown())
     return false;
 
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   SetButtonDown(false);
   SendMessageToFWLWidget(pdfium::MakeUnique<CFWL_MessageMouse>(
       GetNormalWidget(), FWL_MouseCommand::LeftButtonUp, dwFlags,
@@ -457,12 +457,12 @@
 }
 
 bool CXFA_FFField::OnLButtonDblClk(uint32_t dwFlags, const CFX_PointF& point) {
-  if (!GetNormalWidget())
-    return false;
-
   // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
   RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
 
+  if (!GetNormalWidget())
+    return false;
+
   SendMessageToFWLWidget(pdfium::MakeUnique<CFWL_MessageMouse>(
       GetNormalWidget(), FWL_MouseCommand::LeftButtonDblClk, dwFlags,
       FWLToClient(point)));
@@ -471,12 +471,12 @@
 }
 
 bool CXFA_FFField::OnMouseMove(uint32_t dwFlags, const CFX_PointF& point) {
-  if (!GetNormalWidget())
-    return false;
-
   // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
   RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
 
+  if (!GetNormalWidget())
+    return false;
+
   SendMessageToFWLWidget(pdfium::MakeUnique<CFWL_MessageMouse>(
       GetNormalWidget(), FWL_MouseCommand::Move, dwFlags, FWLToClient(point)));
 
@@ -486,12 +486,12 @@
 bool CXFA_FFField::OnMouseWheel(uint32_t dwFlags,
                                 const CFX_PointF& point,
                                 const CFX_Vector& delta) {
-  if (!GetNormalWidget())
-    return false;
-
   // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
   RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
 
+  if (!GetNormalWidget())
+    return false;
+
   SendMessageToFWLWidget(pdfium::MakeUnique<CFWL_MessageMouseWheel>(
       GetNormalWidget(), FWLToClient(point), delta));
 
@@ -528,12 +528,12 @@
 }
 
 bool CXFA_FFField::OnRButtonDblClk(uint32_t dwFlags, const CFX_PointF& point) {
-  if (!GetNormalWidget())
-    return false;
-
   // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
   RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
 
+  if (!GetNormalWidget())
+    return false;
+
   SendMessageToFWLWidget(pdfium::MakeUnique<CFWL_MessageMouse>(
       GetNormalWidget(), FWL_MouseCommand::RightButtonDblClk, dwFlags,
       FWLToClient(point)));
@@ -542,15 +542,15 @@
 }
 
 bool CXFA_FFField::OnSetFocus(CXFA_FFWidget* pOldWidget) {
+  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
+  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
+
   if (!CXFA_FFWidget::OnSetFocus(pOldWidget))
     return false;
 
   if (!GetNormalWidget())
     return false;
 
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   SendMessageToFWLWidget(
       pdfium::MakeUnique<CFWL_MessageSetFocus>(nullptr, GetNormalWidget()));
   GetLayoutItem()->SetStatusBits(XFA_WidgetStatus_Focused);
@@ -574,12 +574,12 @@
 }
 
 bool CXFA_FFField::OnKeyDown(uint32_t dwKeyCode, uint32_t dwFlags) {
-  if (!GetNormalWidget() || !GetDoc()->GetXFADoc()->IsInteractive())
-    return false;
-
   // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
   RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
 
+  if (!GetNormalWidget() || !GetDoc()->GetXFADoc()->IsInteractive())
+    return false;
+
   SendMessageToFWLWidget(pdfium::MakeUnique<CFWL_MessageKey>(
       GetNormalWidget(), FWL_KeyCommand::KeyDown, dwFlags, dwKeyCode));
 
@@ -587,12 +587,12 @@
 }
 
 bool CXFA_FFField::OnKeyUp(uint32_t dwKeyCode, uint32_t dwFlags) {
-  if (!GetNormalWidget() || !GetDoc()->GetXFADoc()->IsInteractive())
-    return false;
-
   // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
   RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
 
+  if (!GetNormalWidget() || !GetDoc()->GetXFADoc()->IsInteractive())
+    return false;
+
   SendMessageToFWLWidget(pdfium::MakeUnique<CFWL_MessageKey>(
       GetNormalWidget(), FWL_KeyCommand::KeyUp, dwFlags, dwKeyCode));
 
@@ -600,6 +600,9 @@
 }
 
 bool CXFA_FFField::OnChar(uint32_t dwChar, uint32_t dwFlags) {
+  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
+  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
+
   if (!GetDoc()->GetXFADoc()->IsInteractive())
     return false;
   if (dwChar == XFA_FWL_VKEY_Tab)
@@ -609,9 +612,6 @@
   if (!m_pNode->IsOpenAccess())
     return false;
 
-  // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
-  RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
-
   SendMessageToFWLWidget(pdfium::MakeUnique<CFWL_MessageKey>(
       GetNormalWidget(), FWL_KeyCommand::Char, dwFlags, dwChar));