CXFA_FFTabOrderPageWidgetIterator must retain layout items for widgets.
This will keep the layout item owning the widget (and hence the
widget itself) alive for the lifetime of the iterator.
Bug: chromium:1060549
Change-Id: Ib5751ef9d302e9adc633ca1001b8a670732dd28e
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/67590
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/testing/resources/javascript/xfa_specific/bug_1060549.evt b/testing/resources/javascript/xfa_specific/bug_1060549.evt
new file mode 100644
index 0000000..cee75e2
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1060549.evt
@@ -0,0 +1,3 @@
+mousedown,left,82,130
+mousedown,left,82,130
+keycode,09
\ No newline at end of file
diff --git a/testing/resources/javascript/xfa_specific/bug_1060549.in b/testing/resources/javascript/xfa_specific/bug_1060549.in
new file mode 100644
index 0000000..2652548
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1060549.in
@@ -0,0 +1,59 @@
+{{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 layout="tb" locale="en_US" name="form1" restoreState="auto">
+ <subform h="10.5in" w="8in" name="subform2">
+ <field h="10mm" name="field1" w="10mm" x="0mm" y="20mm">
+ <ui>
+ <choiceList/>
+ </ui>
+ <items>
+ <text>aaaaaaaaaaaaaaaaaaaaa</text>
+ </items>
+ </field>
+ <field name="field2" h="20mm" w="50mm" x="0mm" y="30mm">
+ <ui>
+ <textEdit>
+ </textEdit>
+ </ui>
+ </field>
+ <subform name="subform3" x="0mm" y="5mm">
+ <occur max="-1"/>
+ <traversal>
+ <traverse operation="next" ref="$xfa.(eval('if (aa == 1) {aa=2;xfa.host.setFocus(cc);bb();xfa.host.openList(cc);}') == 0)"/>
+ </traversal>
+ </subform>
+ </subform>
+ <event activity="initialize">
+ <script contentType="application/x-javascript">
+ aa = 1;
+ </script>
+ </event>
+ <event activity="docReady">
+ <script contentType="application/x-javascript">
+ bb = function() {
+ dd = xfa.resolveNode("xfa.form..subform3");
+ dd.instanceManager.addInstance(1);
+ dd.instanceManager.removeInstance(0);
+ }
+ cc = xfa.resolveNode("xfa.form..field1");
+ </script>
+ </event>
+ </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_ffpageview.cpp b/xfa/fxfa/cxfa_ffpageview.cpp
index 5600ebb..f00a18d 100644
--- a/xfa/fxfa/cxfa_ffpageview.cpp
+++ b/xfa/fxfa/cxfa_ffpageview.cpp
@@ -342,6 +342,7 @@
void CXFA_FFTabOrderPageWidgetIterator::CreateTabOrderWidgetArray() {
m_TabOrderWidgetArray.clear();
+ m_WidgetArrayProtectors.clear();
std::vector<CXFA_FFWidget*> SpaceOrderWidgetArray;
CreateSpaceOrderWidgetArray(&SpaceOrderWidgetArray);
@@ -354,6 +355,7 @@
nWidgetCount) {
if (!pdfium::ContainsValue(m_TabOrderWidgetArray, hWidget)) {
m_TabOrderWidgetArray.emplace_back(hWidget);
+ m_WidgetArrayProtectors.emplace_back(hWidget->GetLayoutItem());
CXFA_Node* pNode = hWidget->GetNode();
if (pNode->GetFFWidgetType() == XFA_FFWidgetType::kExclGroup) {
auto it = std::find(SpaceOrderWidgetArray.begin(),
@@ -366,9 +368,10 @@
SpaceOrderWidgetArray[iWidgetIndex % nWidgetCount];
if (radio->GetNode()->GetExclGroupIfExists() != pNode)
break;
- if (!pdfium::ContainsValue(m_TabOrderWidgetArray, hWidget))
+ if (!pdfium::ContainsValue(m_TabOrderWidgetArray, hWidget)) {
m_TabOrderWidgetArray.emplace_back(radio);
-
+ m_WidgetArrayProtectors.emplace_back(radio->GetLayoutItem());
+ }
iWidgetIndex++;
}
}
diff --git a/xfa/fxfa/cxfa_ffpageview.h b/xfa/fxfa/cxfa_ffpageview.h
index 99f820e..69a27fc 100644
--- a/xfa/fxfa/cxfa_ffpageview.h
+++ b/xfa/fxfa/cxfa_ffpageview.h
@@ -11,6 +11,7 @@
#include <vector>
#include "core/fxcrt/observed_ptr.h"
+#include "core/fxcrt/retain_ptr.h"
#include "xfa/fxfa/layout/cxfa_contentlayoutitem.h"
#include "xfa/fxfa/layout/cxfa_traversestrategy_layoutitem.h"
#include "xfa/fxfa/layout/cxfa_viewlayoutitem.h"
@@ -108,6 +109,7 @@
bool* bContentArea,
bool bMasterPage);
+ std::vector<RetainPtr<CXFA_ContentLayoutItem>> m_WidgetArrayProtectors;
std::vector<UnownedPtr<CXFA_FFWidget>> m_TabOrderWidgetArray;
UnownedPtr<CXFA_FFPageView> const m_pPageView;
const uint32_t m_dwFilter;