summaryrefslogtreecommitdiff
path: root/xfa/fxfa/parser
diff options
context:
space:
mode:
Diffstat (limited to 'xfa/fxfa/parser')
-rw-r--r--xfa/fxfa/parser/cxfa_datadata.cpp4
-rw-r--r--xfa/fxfa/parser/cxfa_datadata.h3
-rw-r--r--xfa/fxfa/parser/cxfa_document.cpp4
-rw-r--r--xfa/fxfa/parser/cxfa_filldata.h2
-rw-r--r--xfa/fxfa/parser/cxfa_itemlayoutprocessor.cpp3
-rw-r--r--xfa/fxfa/parser/cxfa_layoutpagemgr.cpp3
-rw-r--r--xfa/fxfa/parser/cxfa_node.cpp113
-rw-r--r--xfa/fxfa/parser/cxfa_node.h3
-rw-r--r--xfa/fxfa/parser/xfa_document_datamerger_imp.cpp8
9 files changed, 73 insertions, 70 deletions
diff --git a/xfa/fxfa/parser/cxfa_datadata.cpp b/xfa/fxfa/parser/cxfa_datadata.cpp
index cf813fc017..b08801a386 100644
--- a/xfa/fxfa/parser/cxfa_datadata.cpp
+++ b/xfa/fxfa/parser/cxfa_datadata.cpp
@@ -61,6 +61,10 @@ FX_ARGB CXFA_DataData::ToColor(const WideStringView& wsValue) {
return (0xff << 24) | (r << 16) | (g << 8) | b;
}
+CXFA_DataData::CXFA_DataData(CXFA_Node* pNode) : m_pNode(pNode) {}
+
+CXFA_DataData::~CXFA_DataData() {}
+
XFA_Element CXFA_DataData::GetElementType() const {
return m_pNode ? m_pNode->GetElementType() : XFA_Element::Unknown;
}
diff --git a/xfa/fxfa/parser/cxfa_datadata.h b/xfa/fxfa/parser/cxfa_datadata.h
index 5be86c28ab..a05b5024fe 100644
--- a/xfa/fxfa/parser/cxfa_datadata.h
+++ b/xfa/fxfa/parser/cxfa_datadata.h
@@ -17,7 +17,8 @@ class CXFA_DataData {
public:
static FX_ARGB ToColor(const WideStringView& wsValue);
- explicit CXFA_DataData(CXFA_Node* pNode) : m_pNode(pNode) {}
+ explicit CXFA_DataData(CXFA_Node* pNode);
+ virtual ~CXFA_DataData();
explicit operator bool() const { return !!m_pNode; }
CXFA_Node* GetNode() const { return m_pNode; }
diff --git a/xfa/fxfa/parser/cxfa_document.cpp b/xfa/fxfa/parser/cxfa_document.cpp
index 44fc9089c1..edae6c3837 100644
--- a/xfa/fxfa/parser/cxfa_document.cpp
+++ b/xfa/fxfa/parser/cxfa_document.cpp
@@ -94,6 +94,10 @@ CXFA_Document::CXFA_Document(CXFA_DocumentParser* pParser)
}
CXFA_Document::~CXFA_Document() {
+ // Remove all the bindings before freeing the node as the ownership is wonky.
+ if (m_pRootNode)
+ m_pRootNode->ReleaseBindingNodes();
+
delete m_pRootNode;
PurgeNodes();
}
diff --git a/xfa/fxfa/parser/cxfa_filldata.h b/xfa/fxfa/parser/cxfa_filldata.h
index 290e0b72e1..7faca4a95a 100644
--- a/xfa/fxfa/parser/cxfa_filldata.h
+++ b/xfa/fxfa/parser/cxfa_filldata.h
@@ -16,7 +16,7 @@ class CXFA_Node;
class CXFA_FillData : public CXFA_DataData {
public:
explicit CXFA_FillData(CXFA_Node* pNode);
- ~CXFA_FillData();
+ ~CXFA_FillData() override;
int32_t GetPresence();
FX_ARGB GetColor(bool bText = false);
diff --git a/xfa/fxfa/parser/cxfa_itemlayoutprocessor.cpp b/xfa/fxfa/parser/cxfa_itemlayoutprocessor.cpp
index cd6e57ce02..bf63a2a56c 100644
--- a/xfa/fxfa/parser/cxfa_itemlayoutprocessor.cpp
+++ b/xfa/fxfa/parser/cxfa_itemlayoutprocessor.cpp
@@ -2106,8 +2106,7 @@ void CXFA_ItemLayoutProcessor::ProcessUnUseBinds(CXFA_Node* pFormNode) {
CXFA_Node* pBindNode = pNode->GetBindData();
if (pBindNode) {
pBindNode->RemoveBindItem(pNode);
- pNode->JSNode()->SetObject(XFA_Attribute::BindingNode, nullptr,
- nullptr);
+ pNode->JSNode()->SetBindingNode(nullptr);
}
}
pNode->SetFlag(XFA_NodeFlag_UnusedNode, true);
diff --git a/xfa/fxfa/parser/cxfa_layoutpagemgr.cpp b/xfa/fxfa/parser/cxfa_layoutpagemgr.cpp
index 72f5594982..7a013a9a9b 100644
--- a/xfa/fxfa/parser/cxfa_layoutpagemgr.cpp
+++ b/xfa/fxfa/parser/cxfa_layoutpagemgr.cpp
@@ -1698,8 +1698,7 @@ void CXFA_LayoutPageMgr::MergePageSetContents() {
CXFA_Node* pBindNode = pNode->GetBindData();
if (pBindNode) {
pBindNode->RemoveBindItem(pNode);
- pNode->JSNode()->SetObject(XFA_Attribute::BindingNode, nullptr,
- nullptr);
+ pNode->JSNode()->SetBindingNode(nullptr);
}
}
pNode->SetFlag(XFA_NodeFlag_UnusedNode, true);
diff --git a/xfa/fxfa/parser/cxfa_node.cpp b/xfa/fxfa/parser/cxfa_node.cpp
index 6ec3b98f7b..c667c08d10 100644
--- a/xfa/fxfa/parser/cxfa_node.cpp
+++ b/xfa/fxfa/parser/cxfa_node.cpp
@@ -41,13 +41,6 @@
namespace {
-void XFA_DataNodeDeleteBindItem(void* pData) {
- delete static_cast<std::vector<CXFA_Node*>*>(pData);
-}
-
-XFA_MAPDATABLOCKCALLBACKINFO deleteBindItemCallBack = {
- XFA_DataNodeDeleteBindItem, nullptr};
-
std::vector<CXFA_Node*> NodesSortedByDocumentIdx(
const std::set<CXFA_Node*>& rgNodeSet) {
if (rgNodeSet.empty())
@@ -177,6 +170,7 @@ CXFA_Node::CXFA_Node(CXFA_Document* pDoc,
CXFA_Node::~CXFA_Node() {
ASSERT(!m_pParent);
+
CXFA_Node* pNode = m_pChild;
while (pNode) {
CXFA_Node* pNext = pNode->m_pNext;
@@ -222,7 +216,7 @@ CXFA_Node* CXFA_Node::Clone(bool bRecursive) {
}
}
pClone->SetFlag(XFA_NodeFlag_Initialized, true);
- pClone->JSNode()->SetObject(XFA_Attribute::BindingNode, nullptr, nullptr);
+ pClone->JSNode()->SetBindingNode(nullptr);
return pClone;
}
@@ -384,86 +378,79 @@ void CXFA_Node::SetTemplateNode(CXFA_Node* pTemplateNode) {
CXFA_Node* CXFA_Node::GetBindData() {
ASSERT(GetPacketID() == XFA_XDPPACKET_Form);
- return static_cast<CXFA_Node*>(
- JSNode()->GetObject(XFA_Attribute::BindingNode));
+ return JSNode()->GetBindingNode();
}
-std::vector<CXFA_Node*> CXFA_Node::GetBindItems() {
- if (BindsFormItems()) {
- void* pBinding = nullptr;
- JSNode()->TryObject(XFA_Attribute::BindingNode, pBinding);
- return *static_cast<std::vector<CXFA_Node*>*>(pBinding);
- }
- std::vector<CXFA_Node*> result;
- CXFA_Node* pFormNode =
- static_cast<CXFA_Node*>(JSNode()->GetObject(XFA_Attribute::BindingNode));
- if (pFormNode)
- result.push_back(pFormNode);
- return result;
+std::vector<UnownedPtr<CXFA_Node>>* CXFA_Node::GetBindItems() {
+ return JSNode()->GetBindingNodes();
}
int32_t CXFA_Node::AddBindItem(CXFA_Node* pFormNode) {
ASSERT(pFormNode);
+
if (BindsFormItems()) {
- void* pBinding = nullptr;
- JSNode()->TryObject(XFA_Attribute::BindingNode, pBinding);
- auto* pItems = static_cast<std::vector<CXFA_Node*>*>(pBinding);
- if (!pdfium::ContainsValue(*pItems, pFormNode))
- pItems->push_back(pFormNode);
- return pdfium::CollectionSize<int32_t>(*pItems);
+ std::vector<UnownedPtr<CXFA_Node>>* nodes = JSNode()->GetBindingNodes();
+ bool found = false;
+ for (auto& v : *nodes) {
+ if (v.Get() == pFormNode) {
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ nodes->emplace_back(pFormNode);
+ return pdfium::CollectionSize<int32_t>(*nodes);
}
- CXFA_Node* pOldFormItem =
- static_cast<CXFA_Node*>(JSNode()->GetObject(XFA_Attribute::BindingNode));
+
+ CXFA_Node* pOldFormItem = JSNode()->GetBindingNode();
if (!pOldFormItem) {
- JSNode()->SetObject(XFA_Attribute::BindingNode, pFormNode, nullptr);
+ JSNode()->SetBindingNode(pFormNode);
return 1;
}
if (pOldFormItem == pFormNode)
return 1;
- std::vector<CXFA_Node*>* pItems = new std::vector<CXFA_Node*>;
- JSNode()->SetObject(XFA_Attribute::BindingNode, pItems,
- &deleteBindItemCallBack);
- pItems->push_back(pOldFormItem);
- pItems->push_back(pFormNode);
+ std::vector<UnownedPtr<CXFA_Node>> items;
+ items.emplace_back(pOldFormItem);
+ items.emplace_back(pFormNode);
+ JSNode()->SetBindingNodes(std::move(items));
+
m_uNodeFlags |= XFA_NodeFlag_BindFormItems;
return 2;
}
int32_t CXFA_Node::RemoveBindItem(CXFA_Node* pFormNode) {
if (BindsFormItems()) {
- void* pBinding = nullptr;
- JSNode()->TryObject(XFA_Attribute::BindingNode, pBinding);
- auto* pItems = static_cast<std::vector<CXFA_Node*>*>(pBinding);
- auto iter = std::find(pItems->begin(), pItems->end(), pFormNode);
- if (iter != pItems->end()) {
- *iter = pItems->back();
- pItems->pop_back();
- if (pItems->size() == 1) {
- JSNode()->SetObject(XFA_Attribute::BindingNode, (*pItems)[0],
- nullptr); // Invalidates pItems.
- m_uNodeFlags &= ~XFA_NodeFlag_BindFormItems;
- return 1;
- }
+ std::vector<UnownedPtr<CXFA_Node>>* nodes = JSNode()->GetBindingNodes();
+
+ auto it = std::find_if(nodes->begin(), nodes->end(),
+ [&pFormNode](const UnownedPtr<CXFA_Node>& node) {
+ return node.Get() == pFormNode;
+ });
+ if (it != nodes->end())
+ nodes->erase(it);
+
+ if (nodes->size() == 1) {
+ m_uNodeFlags &= ~XFA_NodeFlag_BindFormItems;
+ return 1;
}
- return pdfium::CollectionSize<int32_t>(*pItems);
+ return pdfium::CollectionSize<int32_t>(*nodes);
}
- CXFA_Node* pOldFormItem =
- static_cast<CXFA_Node*>(JSNode()->GetObject(XFA_Attribute::BindingNode));
+
+ CXFA_Node* pOldFormItem = JSNode()->GetBindingNode();
if (pOldFormItem != pFormNode)
return pOldFormItem ? 1 : 0;
- JSNode()->SetObject(XFA_Attribute::BindingNode, nullptr, nullptr);
+ JSNode()->SetBindingNode(nullptr);
return 0;
}
bool CXFA_Node::HasBindItem() {
- return GetPacketID() == XFA_XDPPACKET_Datasets &&
- JSNode()->GetObject(XFA_Attribute::BindingNode);
+ return GetPacketID() == XFA_XDPPACKET_Datasets && JSNode()->GetBindingNode();
}
CXFA_WidgetData* CXFA_Node::GetWidgetData() {
- return (CXFA_WidgetData*)JSNode()->GetObject(XFA_Attribute::WidgetData);
+ return JSNode()->GetWidgetData();
}
CXFA_WidgetData* CXFA_Node::GetContainerWidgetData() {
@@ -494,7 +481,7 @@ CXFA_WidgetData* CXFA_Node::GetContainerWidgetData() {
if (!pDataNode)
return nullptr;
pFieldWidgetData = nullptr;
- for (CXFA_Node* pFormNode : pDataNode->GetBindItems()) {
+ for (const auto& pFormNode : *(pDataNode->GetBindItems())) {
if (!pFormNode || pFormNode->HasRemovedChildren())
continue;
pFieldWidgetData = pFormNode->GetWidgetData();
@@ -1016,6 +1003,15 @@ void CXFA_Node::ClearFlag(uint32_t dwFlag) {
m_uNodeFlags &= ~dwFlag;
}
+void CXFA_Node::ReleaseBindingNodes() {
+ // Clear any binding nodes set on our JS node as we don't necessarily destruct
+ // in an order that makes sense.
+ JSNode()->ReleaseBindingNodes();
+
+ for (CXFA_Node* pNode = m_pChild; pNode; pNode = pNode->m_pNext)
+ pNode->ReleaseBindingNodes();
+}
+
bool CXFA_Node::IsAttributeInXML() {
return JSNode()->GetEnum(XFA_Attribute::Contains) ==
XFA_ATTRIBUTEENUM_MetaData;
@@ -1212,8 +1208,7 @@ void CXFA_Node::RemoveItem(CXFA_Node* pRemoveInstance,
pDataParent->RemoveChild(pDataNode, true);
}
}
- pFormNode->JSNode()->SetObject(XFA_Attribute::BindingNode, nullptr,
- nullptr);
+ pFormNode->JSNode()->SetBindingNode(nullptr);
}
}
diff --git a/xfa/fxfa/parser/cxfa_node.h b/xfa/fxfa/parser/cxfa_node.h
index 66a3174901..dc4710a9c6 100644
--- a/xfa/fxfa/parser/cxfa_node.h
+++ b/xfa/fxfa/parser/cxfa_node.h
@@ -82,6 +82,7 @@ class CXFA_Node : public CXFA_Object {
bool IsLayoutGeneratedNode() const {
return HasFlag(XFA_NodeFlag_LayoutGeneratedNode);
}
+ void ReleaseBindingNodes();
bool BindsFormItems() const { return HasFlag(XFA_NodeFlag_BindFormItems); }
bool HasRemovedChildren() const {
return HasFlag(XFA_NodeFlag_HasRemovedChildren);
@@ -119,7 +120,7 @@ class CXFA_Node : public CXFA_Object {
CXFA_Node* GetDataDescriptionNode();
void SetDataDescriptionNode(CXFA_Node* pDataDescriptionNode);
CXFA_Node* GetBindData();
- std::vector<CXFA_Node*> GetBindItems();
+ std::vector<UnownedPtr<CXFA_Node>>* GetBindItems();
int32_t AddBindItem(CXFA_Node* pFormNode);
int32_t RemoveBindItem(CXFA_Node* pFormNode);
bool HasBindItem();
diff --git a/xfa/fxfa/parser/xfa_document_datamerger_imp.cpp b/xfa/fxfa/parser/xfa_document_datamerger_imp.cpp
index 89a6500fa6..3a70135aea 100644
--- a/xfa/fxfa/parser/xfa_document_datamerger_imp.cpp
+++ b/xfa/fxfa/parser/xfa_document_datamerger_imp.cpp
@@ -122,8 +122,7 @@ bool FormValueNode_SetChildContent(CXFA_Node* pValueNode,
void CreateDataBinding(CXFA_Node* pFormNode,
CXFA_Node* pDataNode,
bool bDataToForm) {
- pFormNode->JSNode()->SetObject(XFA_Attribute::BindingNode, pDataNode,
- nullptr);
+ pFormNode->JSNode()->SetBindingNode(pDataNode);
pDataNode->AddBindItem(pFormNode);
XFA_Element eType = pFormNode->GetElementType();
if (eType != XFA_Element::Field && eType != XFA_Element::ExclGroup)
@@ -1544,10 +1543,11 @@ void CXFA_Document::DoDataRemerge(bool bDoDataMerge) {
if (pFormRoot) {
while (CXFA_Node* pNode = pFormRoot->GetNodeItem(XFA_NODEITEM_FirstChild))
pFormRoot->RemoveChild(pNode, true);
- pFormRoot->JSNode()->SetObject(XFA_Attribute::BindingNode, nullptr,
- nullptr);
+
+ pFormRoot->JSNode()->SetBindingNode(nullptr);
}
m_rgGlobalBinding.clear();
+
if (bDoDataMerge)
DoDataMerge();