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