Let CXFA_NodeIteratorTemplate use either unowned or retain pointers
Use it in CXFA_LayoutItemIterator to ensure items that are
being iterated over don't pop out of existence.
Change-Id: I812f3bfaf0d5ce9991ef926a82aa0c9d40780aa7
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/59531
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/xfa/fxfa/layout/cxfa_traversestrategy_layoutitem.h b/xfa/fxfa/layout/cxfa_traversestrategy_layoutitem.h
index d35ce11..f71d708 100644
--- a/xfa/fxfa/layout/cxfa_traversestrategy_layoutitem.h
+++ b/xfa/fxfa/layout/cxfa_traversestrategy_layoutitem.h
@@ -7,6 +7,7 @@
#ifndef XFA_FXFA_LAYOUT_CXFA_TRAVERSESTRATEGY_LAYOUTITEM_H_
#define XFA_FXFA_LAYOUT_CXFA_TRAVERSESTRATEGY_LAYOUTITEM_H_
+#include "core/fxcrt/retain_ptr.h"
#include "xfa/fxfa/layout/cxfa_layoutitem.h"
#include "xfa/fxfa/parser/cxfa_nodeiteratortemplate.h"
@@ -25,6 +26,7 @@
using CXFA_LayoutItemIterator =
CXFA_NodeIteratorTemplate<CXFA_LayoutItem,
- CXFA_TraverseStrategy_LayoutItem>;
+ CXFA_TraverseStrategy_LayoutItem,
+ RetainPtr<CXFA_LayoutItem>>;
#endif // XFA_FXFA_LAYOUT_CXFA_TRAVERSESTRATEGY_LAYOUTITEM_H_
diff --git a/xfa/fxfa/layout/cxfa_viewlayoutprocessor.cpp b/xfa/fxfa/layout/cxfa_viewlayoutprocessor.cpp
index 6e6ba4a..0ff1777 100644
--- a/xfa/fxfa/layout/cxfa_viewlayoutprocessor.cpp
+++ b/xfa/fxfa/layout/cxfa_viewlayoutprocessor.cpp
@@ -1855,9 +1855,7 @@
nPageIdx++;
uint32_t dwRelevant =
XFA_WidgetStatus_Viewable | XFA_WidgetStatus_Printable;
- CXFA_NodeIteratorTemplate<CXFA_LayoutItem,
- CXFA_TraverseStrategy_LayoutItem>
- iterator(pViewItem);
+ CXFA_LayoutItemIterator iterator(pViewItem);
CXFA_LayoutItem* pChildLayoutItem = iterator.GetCurrent();
while (pChildLayoutItem) {
CXFA_ContentLayoutItem* pContentItem =
diff --git a/xfa/fxfa/parser/cxfa_nodeiteratortemplate.h b/xfa/fxfa/parser/cxfa_nodeiteratortemplate.h
index 10543fd..8803efa 100644
--- a/xfa/fxfa/parser/cxfa_nodeiteratortemplate.h
+++ b/xfa/fxfa/parser/cxfa_nodeiteratortemplate.h
@@ -9,7 +9,9 @@
#include "core/fxcrt/unowned_ptr.h"
-template <class NodeType, class TraverseStrategy>
+template <class NodeType,
+ class TraverseStrategy,
+ typename HolderType = UnownedPtr<NodeType>>
class CXFA_NodeIteratorTemplate {
public:
explicit CXFA_NodeIteratorTemplate(NodeType* pRoot)
@@ -24,7 +26,7 @@
m_pCurrent = nullptr;
return false;
}
- m_pCurrent = pNode;
+ m_pCurrent.Reset(pNode);
return true;
}
@@ -32,20 +34,18 @@
if (!m_pRoot)
return nullptr;
if (!m_pCurrent) {
- m_pCurrent = LastDescendant(m_pRoot.Get());
+ m_pCurrent.Reset(LastDescendant(m_pRoot.Get()));
return m_pCurrent.Get();
}
NodeType* pSibling = PreviousSiblingWithinSubtree(m_pCurrent.Get());
if (pSibling) {
- m_pCurrent = LastDescendant(pSibling);
+ m_pCurrent.Reset(LastDescendant(pSibling));
return m_pCurrent.Get();
}
NodeType* pParent = ParentWithinSubtree(m_pCurrent.Get());
- if (pParent) {
- m_pCurrent = pParent;
- return pParent;
- }
- return nullptr;
+ if (pParent)
+ m_pCurrent.Reset(pParent);
+ return pParent;
}
NodeType* MoveToNext() {
@@ -53,7 +53,7 @@
return nullptr;
NodeType* pChild = TraverseStrategy::GetFirstChild(m_pCurrent.Get());
if (pChild) {
- m_pCurrent = pChild;
+ m_pCurrent.Reset(pChild);
return pChild;
}
return SkipChildrenAndMoveToNext();
@@ -66,7 +66,7 @@
while (pNode) {
NodeType* pSibling = NextSiblingWithinSubtree(pNode);
if (pSibling) {
- m_pCurrent = pSibling;
+ m_pCurrent.Reset(pSibling);
return pSibling;
}
pNode = ParentWithinSubtree(pNode);
@@ -77,23 +77,17 @@
private:
bool RootReachableFromNode(NodeType* pNode) {
- if (!pNode)
- return false;
- if (pNode == m_pRoot)
- return true;
- return RootReachableFromNode(TraverseStrategy::GetParent(pNode));
+ return pNode && (pNode == m_pRoot ||
+ RootReachableFromNode(TraverseStrategy::GetParent(pNode)));
}
NodeType* ParentWithinSubtree(NodeType* pNode) {
- if (!pNode || pNode == m_pRoot)
- return nullptr;
- return TraverseStrategy::GetParent(pNode);
+ return pNode && pNode != m_pRoot ? TraverseStrategy::GetParent(pNode)
+ : nullptr;
}
NodeType* NextSiblingWithinSubtree(NodeType* pNode) {
- if (pNode == m_pRoot)
- return nullptr;
- return TraverseStrategy::GetNextSibling(pNode);
+ return pNode != m_pRoot ? TraverseStrategy::GetNextSibling(pNode) : nullptr;
}
NodeType* PreviousSiblingWithinSubtree(NodeType* pNode) {
@@ -124,8 +118,8 @@
return pChild ? LastDescendant(pChild) : pNode;
}
- UnownedPtr<NodeType> m_pRoot;
- UnownedPtr<NodeType> m_pCurrent;
+ HolderType m_pRoot;
+ HolderType m_pCurrent;
};
#endif // XFA_FXFA_PARSER_CXFA_NODEITERATORTEMPLATE_H_