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);