diff options
author | Dan Sinclair <dsinclair@chromium.org> | 2018-05-02 16:02:03 +0000 |
---|---|---|
committer | Chromium commit bot <commit-bot@chromium.org> | 2018-05-02 16:02:03 +0000 |
commit | 70180648ffd01dd3716871758411d2031aaaebbe (patch) | |
tree | 6cc1d7aa3df8c3e343a1ef6f7e032bae8499f6db /xfa | |
parent | 8ab2b2b2869f769dc169b4a96bb67ec596d5278b (diff) | |
download | pdfium-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.cpp | 10 | ||||
-rw-r--r-- | xfa/fxfa/cxfa_ffdoc.h | 5 | ||||
-rw-r--r-- | xfa/fxfa/parser/cxfa_document.cpp | 26 | ||||
-rw-r--r-- | xfa/fxfa/parser/cxfa_document_parser.cpp | 76 | ||||
-rw-r--r-- | xfa/fxfa/parser/cxfa_document_parser.h | 8 | ||||
-rw-r--r-- | xfa/fxfa/parser/cxfa_document_parser_unittest.cpp | 4 | ||||
-rw-r--r-- | xfa/fxfa/parser/cxfa_node.cpp | 79 | ||||
-rw-r--r-- | xfa/fxfa/parser/cxfa_node.h | 11 | ||||
-rw-r--r-- | xfa/fxfa/parser/cxfa_nodeowner.cpp | 13 | ||||
-rw-r--r-- | xfa/fxfa/parser/cxfa_nodeowner.h | 2 | ||||
-rw-r--r-- | xfa/fxfa/parser/cxfa_xmllocale.cpp | 19 | ||||
-rw-r--r-- | xfa/fxfa/parser/cxfa_xmllocale.h | 5 |
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_; }; |