Observe m_pFocusWidget across m_ArrayKeepItems.clear()
Bug: chromium:993771
Change-Id: I24d2d0cb2ea1779b8aa1def9aa6a1dd639284a85
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/59332
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/testing/resources/javascript/xfa_specific/bug_993771.in b/testing/resources/javascript/xfa_specific/bug_993771.in
new file mode 100644
index 0000000..e94fa58
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_993771.in
@@ -0,0 +1,78 @@
+{{header}}
+{{object 1 0}} <<
+ /Type /Catalog
+ /Pages 2 0 R
+ /NeedsRendering true
+ /AcroForm <<
+ /XFA 5 0 R
+ >>
+>>
+endobj
+{{object 2 0}} <<
+ /Type /Pages
+ /Count 1
+ /Kids [4 0 R]
+>>
+endobj
+{{object 4 0}} <<
+ /Type /Page
+ /Parent 2 0 R
+ /MediaBox [ 0 0 795 842 ]
+>>
+endobj
+{{object 5 0}} <<
+ {{streamlen}}
+>>
+stream
+<xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">
+<template>
+ <subform id="subformId_0" mergeMode="consumeData" name="subform_0">
+ <event activity="docReady">
+ <script contentType="application/x-javascript">
+ xfa.resolveNode("xfa.form.subform_0.subform_1").layout = "tb";
+ </script>
+ </event>
+ <subform id="subformId_1" layout="table" mergeMode="consumeData" name="subform_1" >
+ <field id="fieldId_2" name="field_2" >
+ <event activity="docReady" >
+ <script contentType="application/x-javascript">
+ xfa.resolveNode("xfa.form.subform_0.subform_2").execValidate();
+ </script>
+ </event>
+ </field>
+ <field id="fieldId_3" name="field_3" >
+ <validate scriptTest="disabled" >
+ <script contentType="application/x-javascript">
+ xfa.resolveNode("xfa.form.subform_0.subform_1").keep.next = "pageArea";
+ </script>
+ </validate>
+ </field>
+ </subform>
+ <subformSet>
+ <breakBefore id="breakBeforeId_3" startNew="0" ></breakBefore>
+ <subform allowMacro="1" id="subformId_2" mergeMode="consumeData" name="subform_2" >
+ <field id="fieldId_5" name="field_5" >
+ <validate scriptTest="disabled" >
+ <script contentType="application/x-javascript">
+ xfa.host.setFocus("xfa.form.subform_0.subform_1.field_3");
+ </script>
+ </validate>
+ </field>
+ <field id="fieldId_6" name="field_6" >
+ <validate scriptTest="disabled" >
+ <script contentType="application/x-javascript">
+ xfa.resolveNode("xfa.form.subform_0.subform_1").layout = "position";
+ </script>
+ </validate>
+ </field>
+ </subform>
+ </subformSet>
+ </subform>
+</template>
+</xdp:xdp>
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/javascript/xfa_specific/bug_993771_expected.txt b/testing/resources/javascript/xfa_specific/bug_993771_expected.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_993771_expected.txt
diff --git a/xfa/fxfa/cxfa_ffdocview.cpp b/xfa/fxfa/cxfa_ffdocview.cpp
index 9016c55..97a2883 100644
--- a/xfa/fxfa/cxfa_ffdocview.cpp
+++ b/xfa/fxfa/cxfa_ffdocview.cpp
@@ -300,10 +300,10 @@
if (pNewFocus) {
CXFA_Node* node = pNewFocus->GetNode();
m_pFocusNode = node->IsWidgetReady() ? node : nullptr;
- m_pFocusWidget = pNewFocus;
+ m_pFocusWidget.Reset(pNewFocus);
} else {
m_pFocusNode = nullptr;
- m_pFocusWidget = nullptr;
+ m_pFocusWidget.Reset();
}
return true;
@@ -329,7 +329,7 @@
return;
m_pFocusNode = nullptr;
- m_pFocusWidget = nullptr;
+ m_pFocusWidget.Reset();
}
static XFA_EventError XFA_ProcessEvent(CXFA_FFDocView* pDocView,
diff --git a/xfa/fxfa/cxfa_ffdocview.h b/xfa/fxfa/cxfa_ffdocview.h
index e9a094f..092616e 100644
--- a/xfa/fxfa/cxfa_ffdocview.h
+++ b/xfa/fxfa/cxfa_ffdocview.h
@@ -11,14 +11,15 @@
#include <memory>
#include <vector>
+#include "core/fxcrt/observed_ptr.h"
#include "core/fxcrt/unowned_ptr.h"
#include "xfa/fxfa/cxfa_eventparam.h"
#include "xfa/fxfa/cxfa_ffdoc.h"
+#include "xfa/fxfa/cxfa_ffwidget.h"
#include "xfa/fxfa/fxfa.h"
class CXFA_BindItems;
class CXFA_FFDoc;
-class CXFA_FFWidget;
class CXFA_FFWidgetHandler;
class CXFA_Node;
class CXFA_ReadyNodeIterator;
@@ -120,7 +121,7 @@
std::unique_ptr<CXFA_FFWidgetHandler> m_pWidgetHandler;
UnownedPtr<CXFA_LayoutProcessor> m_pXFADocLayout;
UnownedPtr<CXFA_Node> m_pFocusNode;
- UnownedPtr<CXFA_FFWidget> m_pFocusWidget;
+ ObservedPtr<CXFA_FFWidget> m_pFocusWidget;
std::deque<CXFA_Node*> m_ValidateNodes;
std::vector<CXFA_Node*> m_CalculateNodes;
std::deque<CXFA_BindItems*> m_BindItems;