summaryrefslogtreecommitdiff
path: root/xfa
diff options
context:
space:
mode:
authorDan Sinclair <dsinclair@chromium.org>2018-05-02 16:02:03 +0000
committerChromium commit bot <commit-bot@chromium.org>2018-05-02 16:02:03 +0000
commit70180648ffd01dd3716871758411d2031aaaebbe (patch)
tree6cc1d7aa3df8c3e343a1ef6f7e032bae8499f6db /xfa
parent8ab2b2b2869f769dc169b4a96bb67ec596d5278b (diff)
downloadpdfium-70180648ffd01dd3716871758411d2031aaaebbe.tar.xz
Add a CFX_XMLDocument class.
This CL adds a CFX_XMLDocument to act as the XML node container. All nodes are now owned by the document and the document is returned by the CFX_XMLParser. Classes which parse XML files now store the document instead of the root node. BUG: chromium:835636 Change-Id: I1e07d6115cf14714911d6fd4c3fa920c94fd5faf Reviewed-on: https://pdfium-review.googlesource.com/31313 Reviewed-by: Henrique Nakashima <hnakashima@chromium.org> Commit-Queue: dsinclair <dsinclair@chromium.org>
Diffstat (limited to 'xfa')
-rw-r--r--xfa/fxfa/cxfa_ffdoc.cpp10
-rw-r--r--xfa/fxfa/cxfa_ffdoc.h5
-rw-r--r--xfa/fxfa/parser/cxfa_document.cpp26
-rw-r--r--xfa/fxfa/parser/cxfa_document_parser.cpp76
-rw-r--r--xfa/fxfa/parser/cxfa_document_parser.h8
-rw-r--r--xfa/fxfa/parser/cxfa_document_parser_unittest.cpp4
-rw-r--r--xfa/fxfa/parser/cxfa_node.cpp79
-rw-r--r--xfa/fxfa/parser/cxfa_node.h11
-rw-r--r--xfa/fxfa/parser/cxfa_nodeowner.cpp13
-rw-r--r--xfa/fxfa/parser/cxfa_nodeowner.h2
-rw-r--r--xfa/fxfa/parser/cxfa_xmllocale.cpp19
-rw-r--r--xfa/fxfa/parser/cxfa_xmllocale.h5
12 files changed, 132 insertions, 126 deletions
diff --git a/xfa/fxfa/cxfa_ffdoc.cpp b/xfa/fxfa/cxfa_ffdoc.cpp
index 3d06c7df27..fb2abe3a72 100644
--- a/xfa/fxfa/cxfa_ffdoc.cpp
+++ b/xfa/fxfa/cxfa_ffdoc.cpp
@@ -18,6 +18,7 @@
#include "core/fxcrt/cfx_seekablemultistream.h"
#include "core/fxcrt/fx_extension.h"
#include "core/fxcrt/fx_memory.h"
+#include "core/fxcrt/xml/cfx_xmldocument.h"
#include "core/fxcrt/xml/cfx_xmlelement.h"
#include "core/fxcrt/xml/cfx_xmlnode.h"
#include "fxjs/xfa/cjx_object.h"
@@ -58,12 +59,11 @@ bool CXFA_FFDoc::ParseDoc(CPDF_Object* pElementXFA) {
return false;
auto stream = pdfium::MakeRetain<CFX_SeekableMultiStream>(xfaStreams);
-
CXFA_DocumentParser parser(m_pDocument.get());
if (!parser.Parse(stream, XFA_PacketType::Xdp))
return false;
- m_pXMLRoot = parser.GetXMLRoot();
+ m_pXMLDoc = parser.GetXMLDoc();
m_pDocument->SetRoot(parser.GetRootNode());
return true;
}
@@ -146,13 +146,11 @@ void CXFA_FFDoc::CloseDoc() {
m_DocView->RunDocClose();
m_DocView.reset();
}
- if (m_pDocument) {
- m_pDocument->ReleaseXMLNodesIfNeeded();
+ if (m_pDocument)
m_pDocument->ClearLayoutData();
- }
m_pDocument.reset();
- m_pXMLRoot.reset();
+ m_pXMLDoc.reset();
m_pNotify.reset();
m_pPDFFontMgr.reset();
m_HashToDibDpiMap.clear();
diff --git a/xfa/fxfa/cxfa_ffdoc.h b/xfa/fxfa/cxfa_ffdoc.h
index dacc246378..356a157437 100644
--- a/xfa/fxfa/cxfa_ffdoc.h
+++ b/xfa/fxfa/cxfa_ffdoc.h
@@ -19,6 +19,7 @@
class CFGAS_PDFFontMgr;
class CFX_ChecksumContext;
class CFX_DIBitmap;
+class CFX_XMLDocument;
class CPDF_Document;
class CPDF_Object;
class CXFA_FFApp;
@@ -59,7 +60,7 @@ class CXFA_FFDoc {
return m_pDocEnvironment.Get();
}
FormType GetFormType() const { return m_FormType; }
-
+ CFX_XMLDocument* GetXMLDocument() const { return m_pXMLDoc.get(); }
CXFA_FFDocView* CreateDocView();
@@ -85,7 +86,7 @@ class CXFA_FFDoc {
UnownedPtr<IXFA_DocEnvironment> const m_pDocEnvironment;
UnownedPtr<CXFA_FFApp> const m_pApp;
UnownedPtr<CPDF_Document> m_pPDFDoc;
- std::unique_ptr<CFX_XMLNode> m_pXMLRoot;
+ std::unique_ptr<CFX_XMLDocument> m_pXMLDoc;
std::unique_ptr<CXFA_FFNotify> m_pNotify;
std::unique_ptr<CXFA_Document> m_pDocument;
std::unique_ptr<CXFA_FFDocView> m_DocView;
diff --git a/xfa/fxfa/parser/cxfa_document.cpp b/xfa/fxfa/parser/cxfa_document.cpp
index 9e5143c5a4..15458826ce 100644
--- a/xfa/fxfa/parser/cxfa_document.cpp
+++ b/xfa/fxfa/parser/cxfa_document.cpp
@@ -11,7 +11,9 @@
#include "core/fxcrt/fx_extension.h"
#include "core/fxcrt/fx_fallthrough.h"
+#include "core/fxcrt/xml/cfx_xmldocument.h"
#include "fxjs/cfxjse_engine.h"
+#include "xfa/fxfa/cxfa_ffdoc.h"
#include "xfa/fxfa/cxfa_ffnotify.h"
#include "xfa/fxfa/parser/cscript_datawindow.h"
#include "xfa/fxfa/parser/cscript_eventpseudomodel.h"
@@ -1628,7 +1630,9 @@ void CXFA_Document::DoDataMerge() {
CXFA_Node* pDatasetsRoot = ToNode(GetXFAObject(XFA_HASHCODE_Datasets));
if (!pDatasetsRoot) {
// Ownership will be passed in the AppendChild below to the XML tree.
- auto pDatasetsXMLNode = pdfium::MakeUnique<CFX_XMLElement>(L"xfa:datasets");
+ auto* pDatasetsXMLNode =
+ notify_->GetHDOC()->GetXMLDocument()->CreateNode<CFX_XMLElement>(
+ L"xfa:datasets");
pDatasetsXMLNode->SetAttribute(L"xmlns:xfa",
L"http://www.xfa.org/schema/xfa-data/1.0/");
pDatasetsRoot =
@@ -1636,10 +1640,10 @@ void CXFA_Document::DoDataMerge() {
pDatasetsRoot->JSObject()->SetCData(XFA_Attribute::Name, L"datasets", false,
false);
- CFX_XMLElement* ref = pDatasetsXMLNode.get();
- m_pRootNode->GetXMLMappingNode()->AppendChild(std::move(pDatasetsXMLNode));
+ m_pRootNode->GetXMLMappingNode()->AppendChild(pDatasetsXMLNode);
m_pRootNode->InsertChild(pDatasetsRoot, nullptr);
- pDatasetsRoot->SetXMLMappingNode(ref);
+
+ pDatasetsRoot->SetXMLMappingNode(pDatasetsXMLNode);
}
CXFA_Node *pDataRoot = nullptr, *pDDRoot = nullptr;
@@ -1672,8 +1676,11 @@ void CXFA_Document::DoDataMerge() {
if (!pDataRoot) {
pDataRoot = CreateNode(XFA_PacketType::Datasets, XFA_Element::DataGroup);
pDataRoot->JSObject()->SetCData(XFA_Attribute::Name, L"data", false, false);
- pDataRoot->SetXMLMappingNode(
- pdfium::MakeUnique<CFX_XMLElement>(L"xfa:data"));
+
+ auto* elem =
+ notify_->GetHDOC()->GetXMLDocument()->CreateNode<CFX_XMLElement>(
+ L"xfa:data");
+ pDataRoot->SetXMLMappingNode(elem);
pDatasetsRoot->InsertChild(pDataRoot, nullptr);
}
@@ -1727,8 +1734,11 @@ void CXFA_Document::DoDataMerge() {
CreateNode(XFA_PacketType::Datasets, XFA_Element::DataGroup));
pDataTopLevel->JSObject()->SetCData(XFA_Attribute::Name, wsDataTopLevelName,
false, false);
- pDataTopLevel->SetXMLMappingNode(
- pdfium::MakeUnique<CFX_XMLElement>(wsDataTopLevelName));
+
+ auto* elem =
+ notify_->GetHDOC()->GetXMLDocument()->CreateNode<CFX_XMLElement>(
+ wsDataTopLevelName);
+ pDataTopLevel->SetXMLMappingNode(elem);
CXFA_Node* pBeforeNode = pDataRoot->GetFirstChild();
pDataRoot->InsertChild(pDataTopLevel, pBeforeNode);
diff --git a/xfa/fxfa/parser/cxfa_document_parser.cpp b/xfa/fxfa/parser/cxfa_document_parser.cpp
index fe246d2300..6f3e56ce4c 100644
--- a/xfa/fxfa/parser/cxfa_document_parser.cpp
+++ b/xfa/fxfa/parser/cxfa_document_parser.cpp
@@ -110,16 +110,6 @@ CFX_XMLNode* GetDocumentNode(CFX_XMLNode* pRootNode) {
return nullptr;
}
-WideString GetElementTagNamespaceURI(CFX_XMLElement* pElement) {
- WideString wsNodeStr = pElement->GetNamespacePrefix();
- WideString wsNamespaceURI;
- if (!XFA_FDEExtension_ResolveNamespaceQualifier(pElement, wsNodeStr,
- &wsNamespaceURI)) {
- return WideString();
- }
- return wsNamespaceURI;
-}
-
bool MatchNodeName(CFX_XMLNode* pNode,
const WideStringView& wsLocalTagName,
const WideStringView& wsNamespaceURIPrefix,
@@ -132,7 +122,7 @@ bool MatchNodeName(CFX_XMLNode* pNode,
if (wsNodeStr != wsLocalTagName)
return false;
- wsNodeStr = GetElementTagNamespaceURI(pElement);
+ wsNodeStr = pElement->GetNamespaceURI();
if (eMatchFlags & XFA_XDPPACKET_FLAGS_NOMATCH)
return true;
if (eMatchFlags & XFA_XDPPACKET_FLAGS_PREFIXMATCH) {
@@ -318,8 +308,8 @@ WideString GetPlainTextFromRichText(CFX_XMLNode* pXMLNode) {
} // namespace
bool XFA_RecognizeRichText(CFX_XMLElement* pRichTextXMLNode) {
- return pRichTextXMLNode && GetElementTagNamespaceURI(pRichTextXMLNode) ==
- L"http://www.w3.org/1999/xhtml";
+ return pRichTextXMLNode &&
+ pRichTextXMLNode->GetNamespaceURI() == L"http://www.w3.org/1999/xhtml";
}
CXFA_DocumentParser::CXFA_DocumentParser(CXFA_Document* pFactory)
@@ -329,30 +319,38 @@ CXFA_DocumentParser::~CXFA_DocumentParser() = default;
bool CXFA_DocumentParser::Parse(const RetainPtr<IFX_SeekableStream>& pStream,
XFA_PacketType ePacketID) {
- m_pNodeTree = LoadXML(pStream);
- if (!m_pNodeTree)
+ xml_doc_ = LoadXML(pStream);
+ if (!xml_doc_)
+ return false;
+
+ CFX_XMLNode* root = GetDocumentNode(xml_doc_->GetRoot());
+ if (!root)
return false;
- m_pRootNode = ParseAsXDPPacket(GetDocumentNode(m_pNodeTree.get()), ePacketID);
+ m_pRootNode = ParseAsXDPPacket(root, ePacketID);
return !!m_pRootNode;
}
CFX_XMLNode* CXFA_DocumentParser::ParseXMLData(const ByteString& wsXML) {
auto pStream = pdfium::MakeRetain<CFX_MemoryStream>(
const_cast<uint8_t*>(wsXML.raw_str()), wsXML.GetLength(), false);
- m_pNodeTree = LoadXML(pStream);
- return m_pNodeTree ? GetDocumentNode(m_pNodeTree.get()) : nullptr;
+ xml_doc_ = LoadXML(pStream);
+ if (!xml_doc_)
+ return nullptr;
+ return GetDocumentNode(xml_doc_->GetRoot());
}
-std::unique_ptr<CFX_XMLNode> CXFA_DocumentParser::LoadXML(
+std::unique_ptr<CFX_XMLDocument> CXFA_DocumentParser::LoadXML(
const RetainPtr<IFX_SeekableStream>& pStream) {
ASSERT(pStream);
- auto root = pdfium::MakeUnique<CFX_XMLElement>(L"ROOT");
- root->AppendChild(pdfium::MakeUnique<CFX_XMLInstruction>(L"xml"));
-
- CFX_XMLParser parser(root.get(), pStream);
- return parser.Parse() ? std::move(root) : nullptr;
+ CFX_XMLParser parser(pStream);
+ std::unique_ptr<CFX_XMLDocument> doc = parser.Parse();
+ if (doc) {
+ doc->GetRoot()->InsertChildNode(doc->CreateNode<CFX_XMLInstruction>(L"xml"),
+ 0);
+ }
+ return doc;
}
void CXFA_DocumentParser::ConstructXFANode(CXFA_Node* pXFANode,
@@ -461,14 +459,15 @@ CXFA_Node* CXFA_DocumentParser::ParseAsXDPPacket_XDP(
CFX_XMLNode* pXMLConfigDOMRoot = nullptr;
CXFA_Node* pXFAConfigDOMRoot = nullptr;
+ const PacketInfo* config_packet_info =
+ GetPacketByIndex(XFA_PacketType::Config);
for (CFX_XMLNode* pChildItem = pXMLDocumentNode->GetFirstChild(); pChildItem;
pChildItem = pChildItem->GetNextSibling()) {
- const PacketInfo* pPacketInfo = GetPacketByIndex(XFA_PacketType::Config);
- if (!MatchNodeName(pChildItem, pPacketInfo->name, pPacketInfo->uri,
- pPacketInfo->flags)) {
+ if (!MatchNodeName(pChildItem, config_packet_info->name,
+ config_packet_info->uri, config_packet_info->flags)) {
continue;
}
- if (pXFARootNode->GetFirstChildByName(pPacketInfo->hash))
+ if (pXFARootNode->GetFirstChildByName(config_packet_info->hash))
return nullptr;
pXMLConfigDOMRoot = pChildItem;
@@ -516,7 +515,7 @@ CXFA_Node* CXFA_DocumentParser::ParseAsXDPPacket_XDP(
if (pXMLTemplateDOMRoot)
return nullptr;
- CXFA_Node* pPacketNode = ParseAsXDPPacket(pElement, ePacket);
+ CXFA_Node* pPacketNode = ParseAsXDPPacket_Template(pElement);
if (pPacketNode) {
pXMLTemplateDOMRoot = pElement;
pXFARootNode->InsertChild(pPacketNode, nullptr);
@@ -658,13 +657,13 @@ CXFA_Node* CXFA_DocumentParser::ParseAsXDPPacket_Data(
return pNode;
}
- MaybeOwned<CFX_XMLNode> pDataXMLNode;
+ CFX_XMLNode* pDataXMLNode = nullptr;
if (MatchNodeName(pXMLDocumentNode, L"data", packet->uri, packet->flags)) {
static_cast<CFX_XMLElement*>(pXMLDocumentNode)
->RemoveAttribute(L"xmlns:xfa");
- pDataXMLNode.Reset(pXMLDocumentNode);
+ pDataXMLNode = pXMLDocumentNode;
} else {
- auto pDataElement = pdfium::MakeUnique<CFX_XMLElement>(L"xfa:data");
+ auto* pDataElement = xml_doc_->CreateNode<CFX_XMLElement>(L"xfa:data");
CFX_XMLNode* pParentXMLNode = pXMLDocumentNode->GetParent();
if (pParentXMLNode)
pParentXMLNode->RemoveChildNode(pXMLDocumentNode);
@@ -676,9 +675,8 @@ CXFA_Node* CXFA_DocumentParser::ParseAsXDPPacket_Data(
}
// The node was either removed from the parent above, or already has no
// parent so we can take ownership.
- pDataElement->AppendChild(
- pdfium::WrapUnique<CFX_XMLNode>(pXMLDocumentNode));
- pDataXMLNode.Reset(std::move(pDataElement));
+ pDataElement->AppendChild(pXMLDocumentNode);
+ pDataXMLNode = pDataElement;
}
if (!pDataXMLNode)
return nullptr;
@@ -689,12 +687,12 @@ CXFA_Node* CXFA_DocumentParser::ParseAsXDPPacket_Data(
return nullptr;
WideString wsLocalName =
- static_cast<CFX_XMLElement*>(pDataXMLNode.Get())->GetLocalTagName();
+ static_cast<CFX_XMLElement*>(pDataXMLNode)->GetLocalTagName();
pNode->JSObject()->SetCData(XFA_Attribute::Name, wsLocalName, false, false);
- if (!DataLoader(pNode, pDataXMLNode.Get(), true))
+ if (!DataLoader(pNode, pDataXMLNode, true))
return nullptr;
- pNode->SetXMLMappingNode(std::move(pDataXMLNode));
+ pNode->SetXMLMappingNode(pDataXMLNode);
return pNode;
}
@@ -915,7 +913,7 @@ void CXFA_DocumentParser::ParseDataGroup(CXFA_Node* pXFANode,
case FX_XMLNODE_Element: {
CFX_XMLElement* pXMLElement = static_cast<CFX_XMLElement*>(pXMLChild);
{
- WideString wsNamespaceURI = GetElementTagNamespaceURI(pXMLElement);
+ WideString wsNamespaceURI = pXMLElement->GetNamespaceURI();
if (wsNamespaceURI == L"http://www.xfa.com/schema/xfa-package/" ||
wsNamespaceURI == L"http://www.xfa.org/schema/xfa-package/" ||
wsNamespaceURI == L"http://www.w3.org/2001/XMLSchema-instance") {
diff --git a/xfa/fxfa/parser/cxfa_document_parser.h b/xfa/fxfa/parser/cxfa_document_parser.h
index d76d5953ac..04ed5abb15 100644
--- a/xfa/fxfa/parser/cxfa_document_parser.h
+++ b/xfa/fxfa/parser/cxfa_document_parser.h
@@ -10,12 +10,12 @@
#include <memory>
#include <utility>
+#include "core/fxcrt/xml/cfx_xmldocument.h"
#include "core/fxcrt/xml/cfx_xmlnode.h"
#include "xfa/fxfa/fxfa_basic.h"
class CXFA_Document;
class CXFA_Node;
-class CFX_XMLDoc;
class CFX_XMLInstruction;
class IFX_SeekableStream;
@@ -30,11 +30,11 @@ class CXFA_DocumentParser {
CFX_XMLNode* ParseXMLData(const ByteString& wsXML);
void ConstructXFANode(CXFA_Node* pXFANode, CFX_XMLNode* pXMLNode);
- std::unique_ptr<CFX_XMLNode> GetXMLRoot() { return std::move(m_pNodeTree); }
+ std::unique_ptr<CFX_XMLDocument> GetXMLDoc() { return std::move(xml_doc_); }
CXFA_Node* GetRootNode() const;
private:
- std::unique_ptr<CFX_XMLNode> LoadXML(
+ std::unique_ptr<CFX_XMLDocument> LoadXML(
const RetainPtr<IFX_SeekableStream>& pStream);
CXFA_Node* ParseAsXDPPacket(CFX_XMLNode* pXMLDocumentNode,
@@ -72,7 +72,7 @@ class CXFA_DocumentParser {
XFA_PacketType ePacketID);
UnownedPtr<CXFA_Document> m_pFactory;
- std::unique_ptr<CFX_XMLNode> m_pNodeTree;
+ std::unique_ptr<CFX_XMLDocument> xml_doc_;
// TODO(dsinclair): Figure out who owns this.
CXFA_Node* m_pRootNode = nullptr;
};
diff --git a/xfa/fxfa/parser/cxfa_document_parser_unittest.cpp b/xfa/fxfa/parser/cxfa_document_parser_unittest.cpp
index 9f68fc143b..b150abc3ea 100644
--- a/xfa/fxfa/parser/cxfa_document_parser_unittest.cpp
+++ b/xfa/fxfa/parser/cxfa_document_parser_unittest.cpp
@@ -17,7 +17,7 @@ class CXFA_DocumentParserTest : public testing::Test {
void TearDown() override {
// Hold the XML tree until we cleanup the document.
- std::unique_ptr<CFX_XMLNode> root = parser_->GetXMLRoot();
+ std::unique_ptr<CFX_XMLDocument> doc = parser_->GetXMLDoc();
parser_ = nullptr;
doc_ = nullptr;
}
@@ -30,7 +30,7 @@ class CXFA_DocumentParserTest : public testing::Test {
std::unique_ptr<CXFA_DocumentParser> parser_;
};
-TEST_F(CXFA_DocumentParserTest, XMLInstructionScriptOff) {
+TEST_F(CXFA_DocumentParserTest, XMLInstructionsScriptOff) {
const char* input =
"<config>\n"
"<?originalXFAVersion http://www.xfa.org/schema/xfa-template/2.7 "
diff --git a/xfa/fxfa/parser/cxfa_node.cpp b/xfa/fxfa/parser/cxfa_node.cpp
index 7a6a2ba7d6..fef6caeb75 100644
--- a/xfa/fxfa/parser/cxfa_node.cpp
+++ b/xfa/fxfa/parser/cxfa_node.cpp
@@ -539,12 +539,6 @@ CXFA_Node::CXFA_Node(CXFA_Document* pDoc,
CXFA_Node::~CXFA_Node() = default;
-void CXFA_Node::ReleaseXMLNodeIfUnowned() {
- // Note, this is intentionally non-recursive. The caller is responsible for
- // triggering this on all the nodes which need it.
- xml_node_.ResetIfUnowned();
-}
-
CXFA_Node* CXFA_Node::Clone(bool bRecursive) {
CXFA_Node* pClone = m_pDocument->CreateNode(m_ePacket, m_elementType);
if (!pClone)
@@ -553,23 +547,36 @@ CXFA_Node* CXFA_Node::Clone(bool bRecursive) {
JSObject()->MergeAllData(pClone);
pClone->UpdateNameHash();
if (IsNeedSavingXMLNode()) {
- std::unique_ptr<CFX_XMLNode> pCloneXML;
+ CFX_XMLNode* pCloneXML;
if (IsAttributeInXML()) {
WideString wsName = JSObject()
->TryAttribute(XFA_Attribute::Name, false)
.value_or(WideString());
- auto pCloneXMLElement = pdfium::MakeUnique<CFX_XMLElement>(wsName);
+ auto* pCloneXMLElement = GetDocument()
+ ->GetNotify()
+ ->GetHDOC()
+ ->GetXMLDocument()
+ ->CreateNode<CFX_XMLElement>(wsName);
+
WideString wsValue = JSObject()->GetCData(XFA_Attribute::Value);
- if (!wsValue.IsEmpty())
- pCloneXMLElement->SetTextData(WideString(wsValue));
+ if (!wsValue.IsEmpty()) {
+ auto* text = GetDocument()
+ ->GetNotify()
+ ->GetHDOC()
+ ->GetXMLDocument()
+ ->CreateNode<CFX_XMLText>(wsValue);
+ pCloneXMLElement->AppendChild(text);
+ }
+
+ pCloneXML = pCloneXMLElement;
- pCloneXML.reset(pCloneXMLElement.release());
pClone->JSObject()->SetEnum(XFA_Attribute::Contains,
XFA_AttributeEnum::Unknown, false);
} else {
- pCloneXML = xml_node_->Clone();
+ pCloneXML = xml_node_->Clone(
+ GetDocument()->GetNotify()->GetHDOC()->GetXMLDocument());
}
- pClone->SetXMLMappingNode(std::move(pCloneXML));
+ pClone->SetXMLMappingNode(pCloneXML);
}
if (bRecursive) {
for (CXFA_Node* pChild = GetFirstChild(); pChild;
@@ -1158,8 +1165,7 @@ void CXFA_Node::InsertChild(int32_t index, CXFA_Node* pNode) {
return;
ASSERT(!pNode->xml_node_->GetParent());
- ASSERT(pNode->xml_node_.IsOwned());
- xml_node_->InsertChildNode(pNode->xml_node_.Release(), index);
+ xml_node_->InsertChildNode(pNode->xml_node_.Get(), index);
}
void CXFA_Node::InsertChild(CXFA_Node* pNode, CXFA_Node* pBeforeNode) {
@@ -1214,13 +1220,7 @@ void CXFA_Node::RemoveChild(CXFA_Node* pNode, bool bNotify) {
return;
if (!pNode->IsAttributeInXML()) {
- // This XML node _must_ be in the xml tree if we arrived here, so it is
- // unowned by the XFA_Node. We turn the nodes pointer into a unique_ptr,
- // remove from the XML tree and then assign the owned pointer back onto the
- // XFA_Node.
- auto node = pdfium::WrapUnique<CFX_XMLNode>(pNode->xml_node_.Get());
- xml_node_->RemoveChildNode(node.get());
- pNode->xml_node_.Reset(std::move(node));
+ xml_node_->RemoveChildNode(pNode->xml_node_.Get());
return;
}
@@ -1237,12 +1237,22 @@ void CXFA_Node::RemoveChild(CXFA_Node* pNode, bool bNotify) {
WideString wsName = pNode->JSObject()
->TryAttribute(XFA_Attribute::Name, false)
.value_or(WideString());
- auto pNewXMLElement = pdfium::MakeUnique<CFX_XMLElement>(wsName);
- WideString wsValue = JSObject()->GetCData(XFA_Attribute::Value);
- if (!wsValue.IsEmpty())
- pNewXMLElement->SetTextData(WideString(wsValue));
- pNode->xml_node_.Reset(std::move(pNewXMLElement));
+ auto* pNewXMLElement = GetDocument()
+ ->GetNotify()
+ ->GetHDOC()
+ ->GetXMLDocument()
+ ->CreateNode<CFX_XMLElement>(wsName);
+ WideString wsValue = JSObject()->GetCData(XFA_Attribute::Value);
+ if (!wsValue.IsEmpty()) {
+ auto* text = GetDocument()
+ ->GetNotify()
+ ->GetHDOC()
+ ->GetXMLDocument()
+ ->CreateNode<CFX_XMLText>(wsValue);
+ pNewXMLElement->AppendChild(text);
+ }
+ pNode->xml_node_ = pNewXMLElement;
pNode->JSObject()->SetEnum(XFA_Attribute::Contains,
XFA_AttributeEnum::Unknown, false);
}
@@ -1384,8 +1394,12 @@ void CXFA_Node::UpdateNameHash() {
CFX_XMLNode* CXFA_Node::CreateXMLMappingNode() {
if (!xml_node_) {
- xml_node_ = pdfium::MakeUnique<CFX_XMLElement>(
- JSObject()->GetCData(XFA_Attribute::Name));
+ xml_node_ = GetDocument()
+ ->GetNotify()
+ ->GetHDOC()
+ ->GetXMLDocument()
+ ->CreateNode<CFX_XMLElement>(
+ JSObject()->GetCData(XFA_Attribute::Name));
}
return xml_node_.Get();
}
@@ -4666,7 +4680,12 @@ void CXFA_Node::SetToXML(const WideString& value) {
if (bDeleteChildren)
elem->DeleteChildren();
- elem->SetTextData(value);
+ auto* text = GetDocument()
+ ->GetNotify()
+ ->GetHDOC()
+ ->GetXMLDocument()
+ ->CreateNode<CFX_XMLText>(value);
+ elem->AppendChild(text);
break;
}
case FX_XMLNODE_Text:
diff --git a/xfa/fxfa/parser/cxfa_node.h b/xfa/fxfa/parser/cxfa_node.h
index 11fc38f4cc..db01983a1a 100644
--- a/xfa/fxfa/parser/cxfa_node.h
+++ b/xfa/fxfa/parser/cxfa_node.h
@@ -157,14 +157,7 @@ class CXFA_Node : public CXFA_Object {
return m_ePacket == XFA_PacketType::Form && IsContainerNode();
}
- void ReleaseXMLNodeIfUnowned();
- void SetXMLMappingNode(MaybeOwned<CFX_XMLNode> node) {
- xml_node_ = std::move(node);
- }
- void SetXMLMappingNode(std::unique_ptr<CFX_XMLNode> node) {
- xml_node_.Reset(std::move(node));
- }
- void SetXMLMappingNode(CFX_XMLNode* node) { xml_node_.Reset(node); }
+ void SetXMLMappingNode(CFX_XMLNode* node) { xml_node_ = node; }
CFX_XMLNode* GetXMLMappingNode() const { return xml_node_.Get(); }
CFX_XMLNode* CreateXMLMappingNode();
bool IsNeedSavingXMLNode();
@@ -510,7 +503,7 @@ class CXFA_Node : public CXFA_Object {
CXFA_Node* first_child_;
CXFA_Node* last_child_;
- MaybeOwned<CFX_XMLNode> xml_node_;
+ UnownedPtr<CFX_XMLNode> xml_node_;
const XFA_PacketType m_ePacket;
uint8_t m_ExecuteRecursionDepth = 0;
uint16_t m_uNodeFlags;
diff --git a/xfa/fxfa/parser/cxfa_nodeowner.cpp b/xfa/fxfa/parser/cxfa_nodeowner.cpp
index dba32dc889..ae6f589616 100644
--- a/xfa/fxfa/parser/cxfa_nodeowner.cpp
+++ b/xfa/fxfa/parser/cxfa_nodeowner.cpp
@@ -15,19 +15,6 @@ CXFA_NodeOwner::CXFA_NodeOwner() = default;
CXFA_NodeOwner::~CXFA_NodeOwner() = default;
-void CXFA_NodeOwner::ReleaseXMLNodesIfNeeded() {
- // Because we don't know what order we'll free the nodes we may end up
- // destroying the XML tree before nodes have been cleaned up that point into
- // it. This will cause the ProbeForLowSeverityLifetimeIssue to fire.
- //
- // This doesn't happen in the destructor because of the ownership semantics
- // between the CXFA_Document and CXFA_DocumentParser. It has to happen before
- // the simple parser is destroyed, but the document has to live longer then
- // the simple parser.
- for (auto& it : nodes_)
- it->ReleaseXMLNodeIfUnowned();
-}
-
CXFA_Node* CXFA_NodeOwner::AddOwnedNode(std::unique_ptr<CXFA_Node> node) {
if (!node)
return nullptr;
diff --git a/xfa/fxfa/parser/cxfa_nodeowner.h b/xfa/fxfa/parser/cxfa_nodeowner.h
index 329b1e3284..2aaabe4118 100644
--- a/xfa/fxfa/parser/cxfa_nodeowner.h
+++ b/xfa/fxfa/parser/cxfa_nodeowner.h
@@ -16,8 +16,6 @@ class CXFA_NodeOwner {
public:
virtual ~CXFA_NodeOwner();
- void ReleaseXMLNodesIfNeeded();
-
CXFA_Node* AddOwnedNode(std::unique_ptr<CXFA_Node> node);
void FreeOwnedNode(CXFA_Node* node);
diff --git a/xfa/fxfa/parser/cxfa_xmllocale.cpp b/xfa/fxfa/parser/cxfa_xmllocale.cpp
index ffb4cd9dde..1922b31d7e 100644
--- a/xfa/fxfa/parser/cxfa_xmllocale.cpp
+++ b/xfa/fxfa/parser/cxfa_xmllocale.cpp
@@ -10,6 +10,7 @@
#include "core/fxcrt/cfx_memorystream.h"
#include "core/fxcrt/fx_codepage.h"
+#include "core/fxcrt/xml/cfx_xmldocument.h"
#include "core/fxcrt/xml/cfx_xmlelement.h"
#include "core/fxcrt/xml/cfx_xmlparser.h"
#include "xfa/fxfa/parser/cxfa_document.h"
@@ -30,18 +31,19 @@ constexpr wchar_t kCurrencySymbol[] = L"currencySymbol";
// static
std::unique_ptr<CXFA_XMLLocale> CXFA_XMLLocale::Create(
pdfium::span<uint8_t> data) {
- auto root = pdfium::MakeUnique<CFX_XMLElement>(L"root");
auto stream =
pdfium::MakeRetain<CFX_MemoryStream>(data.data(), data.size(), false);
- CFX_XMLParser parser(root.get(), stream);
- if (!parser.Parse())
+ CFX_XMLParser parser(stream);
+ auto doc = parser.Parse();
+ if (!doc)
return nullptr;
CFX_XMLElement* locale = nullptr;
- for (auto* child = root->GetFirstChild(); child;
+ for (auto* child = doc->GetRoot()->GetFirstChild(); child;
child = child->GetNextSibling()) {
if (child->GetType() != FX_XMLNODE_Element)
continue;
+
CFX_XMLElement* elem = static_cast<CFX_XMLElement*>(child);
if (elem->GetName() == L"locale") {
locale = elem;
@@ -50,14 +52,13 @@ std::unique_ptr<CXFA_XMLLocale> CXFA_XMLLocale::Create(
}
if (!locale)
return nullptr;
-
- return pdfium::MakeUnique<CXFA_XMLLocale>(std::move(root), locale);
+ return pdfium::MakeUnique<CXFA_XMLLocale>(std::move(doc), locale);
}
-CXFA_XMLLocale::CXFA_XMLLocale(std::unique_ptr<CFX_XMLElement> root,
+CXFA_XMLLocale::CXFA_XMLLocale(std::unique_ptr<CFX_XMLDocument> doc,
CFX_XMLElement* locale)
- : xml_root_(std::move(root)), locale_(locale) {
- ASSERT(xml_root_);
+ : xml_doc_(std::move(doc)), locale_(locale) {
+ ASSERT(xml_doc_);
ASSERT(locale_);
}
diff --git a/xfa/fxfa/parser/cxfa_xmllocale.h b/xfa/fxfa/parser/cxfa_xmllocale.h
index 757c5349d4..de3de41a90 100644
--- a/xfa/fxfa/parser/cxfa_xmllocale.h
+++ b/xfa/fxfa/parser/cxfa_xmllocale.h
@@ -13,13 +13,14 @@
#include "third_party/base/ptr_util.h"
#include "third_party/base/span.h"
+class CFX_XMLDocument;
class CFX_XMLElement;
class CXFA_XMLLocale : public LocaleIface {
public:
static std::unique_ptr<CXFA_XMLLocale> Create(pdfium::span<uint8_t> data);
- explicit CXFA_XMLLocale(std::unique_ptr<CFX_XMLElement> root,
+ explicit CXFA_XMLLocale(std::unique_ptr<CFX_XMLDocument> root,
CFX_XMLElement* locale);
~CXFA_XMLLocale() override;
@@ -49,7 +50,7 @@ class CXFA_XMLLocale : public LocaleIface {
size_t index,
bool bAbbr) const;
- std::unique_ptr<CFX_XMLElement> xml_root_;
+ std::unique_ptr<CFX_XMLDocument> xml_doc_;
UnownedPtr<CFX_XMLElement> locale_;
};