XFA: Do not use UnownedPtr between CXFA_Nodes.
They all have document lifetime and may be removed in any order.
Bug: chromium:907427
Change-Id: Ie37addd435e2607fe083ceb76039bced25b764aa
Reviewed-on: https://pdfium-review.googlesource.com/c/45830
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/fxjs/xfa/cjx_object.cpp b/fxjs/xfa/cjx_object.cpp
index c1c7cbc..44ebcc9 100644
--- a/fxjs/xfa/cjx_object.cpp
+++ b/fxjs/xfa/cjx_object.cpp
@@ -623,8 +623,8 @@
i++;
}
}
- for (const auto& pArrayNode : *(pBind->GetBindItems())) {
- if (pArrayNode.Get() != ToNode(GetXFAObject())) {
+ for (auto* pArrayNode : *(pBind->GetBindItems())) {
+ if (pArrayNode != ToNode(GetXFAObject())) {
pArrayNode->JSObject()->SetContent(wsContent, wsContent, bNotify,
bScriptModify, false);
}
@@ -649,8 +649,8 @@
if (pBindNode && bSyncData) {
pBindNode->JSObject()->SetContent(wsContent, wsXMLValue, bNotify,
bScriptModify, false);
- for (const auto& pArrayNode : *(pBindNode->GetBindItems())) {
- if (pArrayNode.Get() != ToNode(GetXFAObject())) {
+ for (auto* pArrayNode : *(pBindNode->GetBindItems())) {
+ if (pArrayNode != ToNode(GetXFAObject())) {
pArrayNode->JSObject()->SetContent(wsContent, wsContent, bNotify,
true, false);
}
@@ -722,7 +722,7 @@
SetAttributeValue(wsContent, wsXMLValue, bNotify, bScriptModify);
if (pBindNode && bSyncData) {
- for (const auto& pArrayNode : *(pBindNode->GetBindItems())) {
+ for (auto* pArrayNode : *(pBindNode->GetBindItems())) {
pArrayNode->JSObject()->SetContent(wsContent, wsContent, bNotify,
bScriptModify, false);
}
@@ -1453,7 +1453,7 @@
CXFA_Node* pContainerNode = nullptr;
if (ToNode(GetXFAObject())->GetPacketType() == XFA_PacketType::Datasets) {
WideString wsPicture;
- for (const auto& pFormNode : *(ToNode(GetXFAObject())->GetBindItems())) {
+ for (auto* pFormNode : *(ToNode(GetXFAObject())->GetBindItems())) {
if (!pFormNode || pFormNode->HasRemovedChildren())
continue;
diff --git a/xfa/fxfa/parser/cxfa_document.cpp b/xfa/fxfa/parser/cxfa_document.cpp
index f870497..24a03ed 100644
--- a/xfa/fxfa/parser/cxfa_document.cpp
+++ b/xfa/fxfa/parser/cxfa_document.cpp
@@ -1280,13 +1280,7 @@
m_eCurVersionMode(XFA_VERSION_DEFAULT),
m_dwDocFlags(0) {}
-CXFA_Document::~CXFA_Document() {
- // The destruction order of the nodes is not known because they're stored in a
- // list in the document. Therefore. the binding nodes must be released before
- // freeing the nodes to avoid dangling UnownedPtrs.
- if (m_pRootNode)
- m_pRootNode->ReleaseBindingNodes();
-}
+CXFA_Document::~CXFA_Document() = default;
CXFA_LayoutProcessor* CXFA_Document::GetLayoutProcessor() {
if (!m_pLayoutProcessor)
diff --git a/xfa/fxfa/parser/cxfa_node.cpp b/xfa/fxfa/parser/cxfa_node.cpp
index e4899bd..0f2ee99 100644
--- a/xfa/fxfa/parser/cxfa_node.cpp
+++ b/xfa/fxfa/parser/cxfa_node.cpp
@@ -865,17 +865,13 @@
return GetBindingNode();
}
-std::vector<UnownedPtr<CXFA_Node>>* CXFA_Node::GetBindItems() {
- return &binding_nodes_;
-}
-
int32_t CXFA_Node::AddBindItem(CXFA_Node* pFormNode) {
ASSERT(pFormNode);
if (BindsFormItems()) {
bool found = false;
- for (auto& v : binding_nodes_) {
- if (v.Get() == pFormNode) {
+ for (auto* v : binding_nodes_) {
+ if (v == pFormNode) {
found = true;
break;
}
@@ -893,9 +889,9 @@
if (pOldFormItem == pFormNode)
return 1;
- std::vector<UnownedPtr<CXFA_Node>> items;
- items.emplace_back(pOldFormItem);
- items.emplace_back(pFormNode);
+ std::vector<CXFA_Node*> items;
+ items.push_back(pOldFormItem);
+ items.push_back(pFormNode);
binding_nodes_ = std::move(items);
m_uNodeFlags |= XFA_NodeFlag_BindFormItems;
@@ -904,10 +900,8 @@
int32_t CXFA_Node::RemoveBindItem(CXFA_Node* pFormNode) {
if (BindsFormItems()) {
- auto it = std::find_if(binding_nodes_.begin(), binding_nodes_.end(),
- [&pFormNode](const UnownedPtr<CXFA_Node>& node) {
- return node.Get() == pFormNode;
- });
+ auto it =
+ std::find(binding_nodes_.begin(), binding_nodes_.end(), pFormNode);
if (it != binding_nodes_.end())
binding_nodes_.erase(it);
@@ -953,10 +947,10 @@
return nullptr;
CXFA_Node* pFieldNode = nullptr;
- for (const auto& pFormNode : *(pDataNode->GetBindItems())) {
+ for (auto* pFormNode : *(pDataNode->GetBindItems())) {
if (!pFormNode || pFormNode->HasRemovedChildren())
continue;
- pFieldNode = pFormNode->IsWidgetReady() ? pFormNode.Get() : nullptr;
+ pFieldNode = pFormNode->IsWidgetReady() ? pFormNode : nullptr;
if (pFieldNode)
wsPicture = pFieldNode->GetPictureContent(XFA_VALUEPICTURE_DataBind);
if (!wsPicture.IsEmpty())
@@ -1423,16 +1417,6 @@
m_uNodeFlags &= ~dwFlag;
}
-void CXFA_Node::ReleaseBindingNodes() {
- // Clear any binding nodes as we don't necessarily destruct in an order that
- // makes sense.
- for (auto& node : binding_nodes_)
- node.Release();
-
- for (CXFA_Node* pNode = first_child_; pNode; pNode = pNode->next_sibling_)
- pNode->ReleaseBindingNodes();
-}
-
bool CXFA_Node::IsAttributeInXML() {
return JSObject()->GetEnum(XFA_Attribute::Contains) ==
XFA_AttributeEnum::MetaData;
diff --git a/xfa/fxfa/parser/cxfa_node.h b/xfa/fxfa/parser/cxfa_node.h
index e8311f4..6731a3b 100644
--- a/xfa/fxfa/parser/cxfa_node.h
+++ b/xfa/fxfa/parser/cxfa_node.h
@@ -141,10 +141,6 @@
binding_nodes_.emplace_back(node);
}
- // TODO(dsinclair): This should not be needed. Nodes should get un-bound when
- // they're deleted instead of us pointing to bad objects.
- void ReleaseBindingNodes();
-
bool HasRemovedChildren() const {
return HasFlag(XFA_NodeFlag_HasRemovedChildren);
}
@@ -199,7 +195,7 @@
CXFA_Node* GetDataDescriptionNode();
void SetDataDescriptionNode(CXFA_Node* pDataDescriptionNode);
CXFA_Node* GetBindData();
- std::vector<UnownedPtr<CXFA_Node>>* GetBindItems();
+ std::vector<CXFA_Node*>* GetBindItems() { return &binding_nodes_; }
int32_t AddBindItem(CXFA_Node* pFormNode);
int32_t RemoveBindItem(CXFA_Node* pFormNode);
bool HasBindItem();
@@ -469,7 +465,7 @@
CXFA_Node* GetBindingNode() const {
if (binding_nodes_.empty())
return nullptr;
- return binding_nodes_[0].Get();
+ return binding_nodes_[0];
}
bool BindsFormItems() const { return HasFlag(XFA_NodeFlag_BindFormItems); }
bool NeedsInitApp() const { return HasFlag(XFA_NodeFlag_NeedsInitApp); }
@@ -505,8 +501,8 @@
uint8_t m_ExecuteRecursionDepth = 0;
uint16_t m_uNodeFlags = XFA_NodeFlag_None;
uint32_t m_dwNameHash = 0;
- CXFA_Node* m_pAuxNode = nullptr; // Raw, node tree cleanup order.
- std::vector<UnownedPtr<CXFA_Node>> binding_nodes_;
+ CXFA_Node* m_pAuxNode = nullptr; // Raw, node tree cleanup order.
+ std::vector<CXFA_Node*> binding_nodes_; // Raw, node tree cleanup order.
bool m_bIsNull = true;
bool m_bPreNull = true;
bool is_widget_ready_ = false;