Convert |CXFA_FFDocView::m_IndexChangedSubforms| to a deque.
Pop off items one at a time to safely iterate through it. Add a set to
keep track of seen notes to prevent infinite loops.
BUG=chromium:932900
Change-Id: I74eb29262e8ba29097638f7103ef427799a06fc5
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/52971
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
diff --git a/xfa/fxfa/cxfa_ffdocview.cpp b/xfa/fxfa/cxfa_ffdocview.cpp
index 587bcfa..0b069f6 100644
--- a/xfa/fxfa/cxfa_ffdocview.cpp
+++ b/xfa/fxfa/cxfa_ffdocview.cpp
@@ -6,6 +6,7 @@
#include "xfa/fxfa/cxfa_ffdocview.h"
+#include <set>
#include <utility>
#include "core/fxcrt/fx_extension.h"
@@ -463,8 +464,12 @@
}
void CXFA_FFDocView::RunSubformIndexChange() {
- for (CXFA_Node* pSubformNode : m_IndexChangedSubforms) {
- if (!pSubformNode->IsWidgetReady())
+ std::set<CXFA_Node*> seen;
+ while (!m_IndexChangedSubforms.empty()) {
+ CXFA_Node* pSubformNode = m_IndexChangedSubforms.front();
+ m_IndexChangedSubforms.pop_front();
+ bool bInserted = seen.insert(pSubformNode).second;
+ if (!bInserted || !pSubformNode->IsWidgetReady())
continue;
CXFA_EventParam eParam;
@@ -472,7 +477,6 @@
eParam.m_pTarget = pSubformNode;
pSubformNode->ProcessEvent(this, XFA_AttributeValue::IndexChange, &eParam);
}
- m_IndexChangedSubforms.clear();
}
void CXFA_FFDocView::AddNewFormNode(CXFA_Node* pNode) {
@@ -482,7 +486,8 @@
void CXFA_FFDocView::AddIndexChangedSubform(CXFA_Node* pNode) {
ASSERT(pNode->GetElementType() == XFA_Element::Subform);
- m_IndexChangedSubforms.push_back(pNode);
+ if (!pdfium::ContainsValue(m_IndexChangedSubforms, pNode))
+ m_IndexChangedSubforms.push_back(pNode);
}
void CXFA_FFDocView::RunDocClose() {
diff --git a/xfa/fxfa/cxfa_ffdocview.h b/xfa/fxfa/cxfa_ffdocview.h
index b2debf3..91aae15 100644
--- a/xfa/fxfa/cxfa_ffdocview.h
+++ b/xfa/fxfa/cxfa_ffdocview.h
@@ -124,7 +124,7 @@
std::vector<CXFA_Node*> m_CalculateNodes;
std::vector<CXFA_BindItems*> m_BindItems;
std::deque<CXFA_Node*> m_NewAddedNodes;
- std::vector<CXFA_Node*> m_IndexChangedSubforms;
+ std::deque<CXFA_Node*> m_IndexChangedSubforms;
XFA_DOCVIEW_LAYOUTSTATUS m_iStatus = XFA_DOCVIEW_LAYOUTSTATUS_None;
int32_t m_iLock = 0;
};