summaryrefslogtreecommitdiff
path: root/core/fxcrt
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 /core/fxcrt
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 'core/fxcrt')
-rw-r--r--core/fxcrt/xml/cfx_xmlchardata.cpp5
-rw-r--r--core/fxcrt/xml/cfx_xmlchardata.h4
-rw-r--r--core/fxcrt/xml/cfx_xmlchardata_unittest.cpp9
-rw-r--r--core/fxcrt/xml/cfx_xmldocument.cpp14
-rw-r--r--core/fxcrt/xml/cfx_xmldocument.h37
-rw-r--r--core/fxcrt/xml/cfx_xmldocument_unittest.cpp22
-rw-r--r--core/fxcrt/xml/cfx_xmlelement.cpp25
-rw-r--r--core/fxcrt/xml/cfx_xmlelement.h5
-rw-r--r--core/fxcrt/xml/cfx_xmlelement_unittest.cpp82
-rw-r--r--core/fxcrt/xml/cfx_xmlinstruction.cpp9
-rw-r--r--core/fxcrt/xml/cfx_xmlinstruction.h4
-rw-r--r--core/fxcrt/xml/cfx_xmlinstruction_unittest.cpp67
-rw-r--r--core/fxcrt/xml/cfx_xmlnode.cpp90
-rw-r--r--core/fxcrt/xml/cfx_xmlnode.h32
-rw-r--r--core/fxcrt/xml/cfx_xmlnode_unittest.cpp379
-rw-r--r--core/fxcrt/xml/cfx_xmlparser.cpp81
-rw-r--r--core/fxcrt/xml/cfx_xmlparser.h9
-rw-r--r--core/fxcrt/xml/cfx_xmlparser_unittest.cpp99
-rw-r--r--core/fxcrt/xml/cfx_xmltext.cpp5
-rw-r--r--core/fxcrt/xml/cfx_xmltext.h4
-rw-r--r--core/fxcrt/xml/cfx_xmltext_unittest.cpp7
21 files changed, 518 insertions, 471 deletions
diff --git a/core/fxcrt/xml/cfx_xmlchardata.cpp b/core/fxcrt/xml/cfx_xmlchardata.cpp
index e62a43ac53..307d319537 100644
--- a/core/fxcrt/xml/cfx_xmlchardata.cpp
+++ b/core/fxcrt/xml/cfx_xmlchardata.cpp
@@ -6,6 +6,7 @@
#include "core/fxcrt/xml/cfx_xmlchardata.h"
+#include "core/fxcrt/xml/cfx_xmldocument.h"
#include "third_party/base/ptr_util.h"
CFX_XMLCharData::CFX_XMLCharData(const WideString& wsCData)
@@ -17,8 +18,8 @@ FX_XMLNODETYPE CFX_XMLCharData::GetType() const {
return FX_XMLNODE_CharData;
}
-std::unique_ptr<CFX_XMLNode> CFX_XMLCharData::Clone() {
- return pdfium::MakeUnique<CFX_XMLCharData>(GetText());
+CFX_XMLNode* CFX_XMLCharData::Clone(CFX_XMLDocument* doc) {
+ return doc->CreateNode<CFX_XMLCharData>(GetText());
}
void CFX_XMLCharData::Save(
diff --git a/core/fxcrt/xml/cfx_xmlchardata.h b/core/fxcrt/xml/cfx_xmlchardata.h
index 0cdc348f26..013414bc82 100644
--- a/core/fxcrt/xml/cfx_xmlchardata.h
+++ b/core/fxcrt/xml/cfx_xmlchardata.h
@@ -12,6 +12,8 @@
#include "core/fxcrt/fx_string.h"
#include "core/fxcrt/xml/cfx_xmltext.h"
+class CFX_XMLDocument;
+
class CFX_XMLCharData : public CFX_XMLText {
public:
explicit CFX_XMLCharData(const WideString& wsCData);
@@ -19,7 +21,7 @@ class CFX_XMLCharData : public CFX_XMLText {
// CFX_XMLNode
FX_XMLNODETYPE GetType() const override;
- std::unique_ptr<CFX_XMLNode> Clone() override;
+ CFX_XMLNode* Clone(CFX_XMLDocument* doc) override;
void Save(const RetainPtr<IFX_SeekableWriteStream>& pXMLStream) override;
};
diff --git a/core/fxcrt/xml/cfx_xmlchardata_unittest.cpp b/core/fxcrt/xml/cfx_xmlchardata_unittest.cpp
index 0fa48e520f..4f0c49eaac 100644
--- a/core/fxcrt/xml/cfx_xmlchardata_unittest.cpp
+++ b/core/fxcrt/xml/cfx_xmlchardata_unittest.cpp
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "core/fxcrt/xml/cfx_xmlchardata.h"
+#include "core/fxcrt/xml/cfx_xmldocument.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/string_write_stream.h"
#include "testing/test_support.h"
@@ -18,12 +19,14 @@ TEST(CFX_XMLCharDataTest, GetText) {
}
TEST(CFX_XMLCharDataTest, Clone) {
+ CFX_XMLDocument doc;
+
CFX_XMLCharData data(L"My Data");
- auto clone = data.Clone();
+ CFX_XMLNode* clone = data.Clone(&doc);
EXPECT_TRUE(clone != nullptr);
- EXPECT_NE(&data, clone.get());
+ EXPECT_NE(&data, clone);
ASSERT_EQ(FX_XMLNODE_CharData, clone->GetType());
- EXPECT_EQ(L"My Data", static_cast<CFX_XMLCharData*>(clone.get())->GetText());
+ EXPECT_EQ(L"My Data", static_cast<CFX_XMLCharData*>(clone)->GetText());
}
TEST(CFX_XMLCharDataTest, Save) {
diff --git a/core/fxcrt/xml/cfx_xmldocument.cpp b/core/fxcrt/xml/cfx_xmldocument.cpp
new file mode 100644
index 0000000000..f6e55551ed
--- /dev/null
+++ b/core/fxcrt/xml/cfx_xmldocument.cpp
@@ -0,0 +1,14 @@
+// Copyright 2018 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "core/fxcrt/xml/cfx_xmldocument.h"
+#include "core/fxcrt/fx_system.h"
+#include "core/fxcrt/xml/cfx_xmlinstruction.h"
+#include "third_party/base/ptr_util.h"
+
+CFX_XMLDocument::CFX_XMLDocument() {
+ root_ = CreateNode<CFX_XMLElement>(L"root");
+}
+
+CFX_XMLDocument::~CFX_XMLDocument() = default;
diff --git a/core/fxcrt/xml/cfx_xmldocument.h b/core/fxcrt/xml/cfx_xmldocument.h
new file mode 100644
index 0000000000..a568f8390f
--- /dev/null
+++ b/core/fxcrt/xml/cfx_xmldocument.h
@@ -0,0 +1,37 @@
+// Copyright 2018 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CORE_FXCRT_XML_CFX_XMLDOCUMENT_H_
+#define CORE_FXCRT_XML_CFX_XMLDOCUMENT_H_
+
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include "core/fxcrt/unowned_ptr.h"
+#include "core/fxcrt/xml/cfx_xmlelement.h"
+#include "third_party/base/ptr_util.h"
+
+class CFX_XMLInstruction;
+class CFX_XMLNode;
+
+class CFX_XMLDocument {
+ public:
+ CFX_XMLDocument();
+ ~CFX_XMLDocument();
+
+ CFX_XMLElement* GetRoot() const { return root_.Get(); }
+
+ template <typename T, typename... Args>
+ T* CreateNode(Args&&... args) {
+ nodes_.push_back(pdfium::MakeUnique<T>(std::forward<Args>(args)...));
+ return static_cast<T*>(nodes_.back().get());
+ }
+
+ private:
+ std::vector<std::unique_ptr<CFX_XMLNode>> nodes_;
+ UnownedPtr<CFX_XMLElement> root_;
+};
+
+#endif // CORE_FXCRT_XML_CFX_XMLDOCUMENT_H_
diff --git a/core/fxcrt/xml/cfx_xmldocument_unittest.cpp b/core/fxcrt/xml/cfx_xmldocument_unittest.cpp
new file mode 100644
index 0000000000..486b040db5
--- /dev/null
+++ b/core/fxcrt/xml/cfx_xmldocument_unittest.cpp
@@ -0,0 +1,22 @@
+// Copyright 2018 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "core/fxcrt/xml/cfx_xmldocument.h"
+#include "core/fxcrt/xml/cfx_xmlelement.h"
+#include "core/fxcrt/xml/cfx_xmlinstruction.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/test_support.h"
+
+TEST(CFX_XMLDocumentTest, Root) {
+ CFX_XMLDocument doc;
+ EXPECT_TRUE(doc.GetRoot() != nullptr);
+}
+
+TEST(CFX_XMLDocumentTest, CreateNode) {
+ CFX_XMLDocument doc;
+ auto* node = doc.CreateNode<CFX_XMLElement>(L"elem");
+
+ ASSERT_EQ(FX_XMLNODE_Element, node->GetType());
+ EXPECT_EQ(L"elem", node->GetName());
+}
diff --git a/core/fxcrt/xml/cfx_xmlelement.cpp b/core/fxcrt/xml/cfx_xmlelement.cpp
index 3befb242c9..74351b8c58 100644
--- a/core/fxcrt/xml/cfx_xmlelement.cpp
+++ b/core/fxcrt/xml/cfx_xmlelement.cpp
@@ -11,6 +11,7 @@
#include "core/fxcrt/cfx_widetextbuf.h"
#include "core/fxcrt/fx_extension.h"
#include "core/fxcrt/xml/cfx_xmlchardata.h"
+#include "core/fxcrt/xml/cfx_xmldocument.h"
#include "core/fxcrt/xml/cfx_xmltext.h"
#include "third_party/base/ptr_util.h"
#include "third_party/base/stl_util.h"
@@ -26,20 +27,18 @@ FX_XMLNODETYPE CFX_XMLElement::GetType() const {
return FX_XMLNODE_Element;
}
-std::unique_ptr<CFX_XMLNode> CFX_XMLElement::Clone() {
- auto pClone = pdfium::MakeUnique<CFX_XMLElement>(name_);
- pClone->attrs_ = attrs_;
+CFX_XMLNode* CFX_XMLElement::Clone(CFX_XMLDocument* doc) {
+ auto* node = doc->CreateNode<CFX_XMLElement>(name_);
+ node->attrs_ = attrs_;
- // TODO(dsinclair): This clone is wrong. It doesn't clone child nodes just
- // copies text nodes?
- WideString wsText;
+ // TODO(dsinclair): This clone is wrong. It doesn't clone all child nodes just
+ // text nodes?
for (CFX_XMLNode* pChild = GetFirstChild(); pChild;
pChild = pChild->GetNextSibling()) {
if (pChild->GetType() == FX_XMLNODE_Text)
- wsText += static_cast<CFX_XMLText*>(pChild)->GetText();
+ node->AppendChild(pChild->Clone(doc));
}
- pClone->SetTextData(wsText);
- return std::move(pClone);
+ return node;
}
WideString CFX_XMLElement::GetLocalTagName() const {
@@ -60,7 +59,6 @@ WideString CFX_XMLElement::GetNamespaceURI() const {
attr += L":";
attr += wsPrefix;
}
-
const CFX_XMLNode* pNode = this;
while (pNode) {
if (pNode->GetType() != FX_XMLNODE_Element)
@@ -89,13 +87,6 @@ WideString CFX_XMLElement::GetTextData() const {
return buffer.MakeString();
}
-void CFX_XMLElement::SetTextData(const WideString& wsText) {
- // TODO(dsinclair): Shouldn't this remove the children if you set blank text?
- if (wsText.IsEmpty())
- return;
- AppendChild(pdfium::MakeUnique<CFX_XMLText>(wsText));
-}
-
void CFX_XMLElement::Save(
const RetainPtr<IFX_SeekableWriteStream>& pXMLStream) {
ByteString bsNameEncoded = name_.UTF8Encode();
diff --git a/core/fxcrt/xml/cfx_xmlelement.h b/core/fxcrt/xml/cfx_xmlelement.h
index 678ba6d996..ca5fd5e797 100644
--- a/core/fxcrt/xml/cfx_xmlelement.h
+++ b/core/fxcrt/xml/cfx_xmlelement.h
@@ -14,6 +14,8 @@
#include "core/fxcrt/fx_string.h"
#include "core/fxcrt/xml/cfx_xmlnode.h"
+class CFX_XMLDocument;
+
class CFX_XMLElement : public CFX_XMLNode {
public:
explicit CFX_XMLElement(const WideString& wsTag);
@@ -21,7 +23,7 @@ class CFX_XMLElement : public CFX_XMLNode {
// CFX_XMLNode
FX_XMLNODETYPE GetType() const override;
- std::unique_ptr<CFX_XMLNode> Clone() override;
+ CFX_XMLNode* Clone(CFX_XMLDocument* doc) override;
void Save(const RetainPtr<IFX_SeekableWriteStream>& pXMLStream) override;
WideString GetName() const { return name_; }
@@ -44,7 +46,6 @@ class CFX_XMLElement : public CFX_XMLNode {
WideString GetNamespaceURI() const;
WideString GetTextData() const;
- void SetTextData(const WideString& wsText);
private:
WideString AttributeToString(const WideString& name, const WideString& value);
diff --git a/core/fxcrt/xml/cfx_xmlelement_unittest.cpp b/core/fxcrt/xml/cfx_xmlelement_unittest.cpp
index 79e067f511..1e53ef3dd7 100644
--- a/core/fxcrt/xml/cfx_xmlelement_unittest.cpp
+++ b/core/fxcrt/xml/cfx_xmlelement_unittest.cpp
@@ -2,15 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include <utility>
-
-#include "core/fxcrt/xml/cfx_xmlchardata.h"
#include "core/fxcrt/xml/cfx_xmlelement.h"
+#include "core/fxcrt/xml/cfx_xmlchardata.h"
+#include "core/fxcrt/xml/cfx_xmldocument.h"
#include "core/fxcrt/xml/cfx_xmltext.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/string_write_stream.h"
#include "testing/test_support.h"
-#include "third_party/base/ptr_util.h"
TEST(CFX_XMLElementTest, GetType) {
CFX_XMLElement node(L"node");
@@ -74,19 +72,24 @@ TEST(CFX_XMLElementTest, Attributes) {
}
TEST(CFX_XMLElementTest, Clone) {
+ CFX_XMLDocument doc;
+
CFX_XMLElement node(L"test:node");
node.SetAttribute(L"first", L"one");
node.SetAttribute(L"second", L"two");
node.SetAttribute(L"xmlns:test", L"https://example.org/test");
- node.AppendChild(pdfium::MakeUnique<CFX_XMLText>(L"Text Child"));
- node.AppendChild(pdfium::MakeUnique<CFX_XMLElement>(L"Node child"));
+ CFX_XMLText text_child1(L"Text Child");
+ node.AppendChild(&text_child1);
- auto clone = node.Clone();
+ CFX_XMLElement node_child1(L"Node child");
+ node.AppendChild(&node_child1);
+
+ CFX_XMLNode* clone = node.Clone(&doc);
EXPECT_TRUE(clone != nullptr);
ASSERT_EQ(FX_XMLNODE_Element, clone->GetType());
- CFX_XMLElement* inst = static_cast<CFX_XMLElement*>(clone.get());
+ CFX_XMLElement* inst = static_cast<CFX_XMLElement*>(clone);
EXPECT_EQ(L"test:node", inst->GetName());
EXPECT_EQ(L"node", inst->GetLocalTagName());
@@ -129,14 +132,17 @@ TEST(CFX_XMLElementTest, SaveWithChildren) {
auto stream = pdfium::MakeRetain<StringWriteStream>();
CFX_XMLElement node(L"node");
- node.AppendChild(pdfium::MakeUnique<CFX_XMLText>(L"Text Child 1"));
+ CFX_XMLText text_child1(L"Text Child 1");
+ node.AppendChild(&text_child1);
+
+ CFX_XMLElement node_child1(L"node-child");
+ node.AppendChild(&node_child1);
- auto child = pdfium::MakeUnique<CFX_XMLElement>(L"node-child");
- CFX_XMLElement* node_child1 = child.get();
- node.AppendChild(std::move(child));
+ CFX_XMLText text_child2(L"Text Child 2");
+ node_child1.AppendChild(&text_child2);
- node_child1->AppendChild(pdfium::MakeUnique<CFX_XMLText>(L"Text Child 2"));
- node.AppendChild(pdfium::MakeUnique<CFX_XMLCharData>(L"Char Data"));
+ CFX_XMLCharData char_data1(L"Char Data");
+ node.AppendChild(&char_data1);
node.Save(stream);
EXPECT_EQ(
@@ -160,18 +166,18 @@ TEST(CFX_XMLElementTest, SaveWithNamespace) {
TEST(CFX_XMLElementTest, GetFirstChildNamed) {
CFX_XMLElement node(L"node");
- auto child = pdfium::MakeUnique<CFX_XMLElement>(L"node-child");
- CFX_XMLElement* node_child1 = child.get();
- node.AppendChild(std::move(child));
+ CFX_XMLElement node_child1(L"node-child");
+ node.AppendChild(&node_child1);
auto* found = node.GetFirstChildNamed(L"node-child");
EXPECT_TRUE(found != nullptr);
- EXPECT_EQ(node_child1, found);
+ EXPECT_EQ(&node_child1, found);
}
TEST(CFX_XMLElementTest, GetFirstChildNamedMissing) {
CFX_XMLElement node(L"node");
- node.AppendChild(pdfium::MakeUnique<CFX_XMLElement>(L"node-child"));
+ CFX_XMLElement node_child1(L"node-child");
+ node.AppendChild(&node_child1);
auto* found = node.GetFirstChildNamed(L"node-sibling");
EXPECT_TRUE(found == nullptr);
@@ -179,23 +185,26 @@ TEST(CFX_XMLElementTest, GetFirstChildNamedMissing) {
TEST(CFX_XMLElementTest, GetNthChildNamed) {
CFX_XMLElement node(L"node");
- node.AppendChild(pdfium::MakeUnique<CFX_XMLElement>(L"node-child"));
- node.AppendChild(pdfium::MakeUnique<CFX_XMLElement>(L"node-child"));
-
- auto child = pdfium::MakeUnique<CFX_XMLElement>(L"node-child");
- CFX_XMLElement* node_child3 = child.get();
- node.AppendChild(std::move(child));
+ CFX_XMLElement node_child1(L"node-child");
+ CFX_XMLElement node_child2(L"node-child");
+ CFX_XMLElement node_child3(L"node-child");
+ node.AppendChild(&node_child1);
+ node.AppendChild(&node_child2);
+ node.AppendChild(&node_child3);
auto* found = node.GetNthChildNamed(L"node-child", 2);
EXPECT_TRUE(found != nullptr);
- EXPECT_EQ(node_child3, found);
+ EXPECT_EQ(&node_child3, found);
}
TEST(CFX_XMLElementTest, GetNthChildNamedMissingChild) {
CFX_XMLElement node(L"node");
- node.AppendChild(pdfium::MakeUnique<CFX_XMLElement>(L"node-child"));
- node.AppendChild(pdfium::MakeUnique<CFX_XMLElement>(L"node-child"));
- node.AppendChild(pdfium::MakeUnique<CFX_XMLElement>(L"node-child"));
+ CFX_XMLElement node_child1(L"node-child");
+ CFX_XMLElement node_child2(L"node-child");
+ CFX_XMLElement node_child3(L"node-child");
+ node.AppendChild(&node_child1);
+ node.AppendChild(&node_child2);
+ node.AppendChild(&node_child3);
auto* found = node.GetNthChildNamed(L"node-child", 5);
EXPECT_TRUE(found == nullptr);
@@ -203,15 +212,18 @@ TEST(CFX_XMLElementTest, GetNthChildNamedMissingChild) {
TEST(CFX_XMLElementTest, GetTextData) {
CFX_XMLElement node(L"node");
- node.AppendChild(pdfium::MakeUnique<CFX_XMLText>(L"Text Child 1"));
- auto child = pdfium::MakeUnique<CFX_XMLElement>(L"Node child");
- CFX_XMLElement* node_child1 = child.get();
- node.AppendChild(std::move(child));
+ CFX_XMLText text_child1(L"Text Child 1");
+ node.AppendChild(&text_child1);
+
+ CFX_XMLElement node_child1(L"Node child");
+ node.AppendChild(&node_child1);
- node_child1->AppendChild(pdfium::MakeUnique<CFX_XMLText>(L"Text Child 2"));
+ CFX_XMLText text_child2(L"Text Child 2");
+ node_child1.AppendChild(&text_child2);
- node.AppendChild(pdfium::MakeUnique<CFX_XMLCharData>(L"Char Data"));
+ CFX_XMLCharData char_data1(L"Char Data");
+ node.AppendChild(&char_data1);
EXPECT_EQ(L"Text Child 1Char Data", node.GetTextData());
}
diff --git a/core/fxcrt/xml/cfx_xmlinstruction.cpp b/core/fxcrt/xml/cfx_xmlinstruction.cpp
index b7a87b588a..32841fb68e 100644
--- a/core/fxcrt/xml/cfx_xmlinstruction.cpp
+++ b/core/fxcrt/xml/cfx_xmlinstruction.cpp
@@ -10,6 +10,7 @@
#include "core/fxcrt/fx_codepage.h"
#include "core/fxcrt/fx_extension.h"
+#include "core/fxcrt/xml/cfx_xmldocument.h"
#include "third_party/base/ptr_util.h"
#include "third_party/base/stl_util.h"
@@ -22,10 +23,10 @@ FX_XMLNODETYPE CFX_XMLInstruction::GetType() const {
return FX_XMLNODE_Instruction;
}
-std::unique_ptr<CFX_XMLNode> CFX_XMLInstruction::Clone() {
- auto pClone = pdfium::MakeUnique<CFX_XMLInstruction>(name_);
- pClone->m_TargetData = m_TargetData;
- return std::move(pClone);
+CFX_XMLNode* CFX_XMLInstruction::Clone(CFX_XMLDocument* doc) {
+ auto* node = doc->CreateNode<CFX_XMLInstruction>(name_);
+ node->m_TargetData = m_TargetData;
+ return node;
}
void CFX_XMLInstruction::AppendData(const WideString& wsData) {
diff --git a/core/fxcrt/xml/cfx_xmlinstruction.h b/core/fxcrt/xml/cfx_xmlinstruction.h
index 3be9d48573..153ef2b625 100644
--- a/core/fxcrt/xml/cfx_xmlinstruction.h
+++ b/core/fxcrt/xml/cfx_xmlinstruction.h
@@ -13,6 +13,8 @@
#include "core/fxcrt/fx_string.h"
#include "core/fxcrt/xml/cfx_xmlnode.h"
+class CFX_XMLDocument;
+
class CFX_XMLInstruction : public CFX_XMLNode {
public:
explicit CFX_XMLInstruction(const WideString& wsTarget);
@@ -20,7 +22,7 @@ class CFX_XMLInstruction : public CFX_XMLNode {
// CFX_XMLNode
FX_XMLNODETYPE GetType() const override;
- std::unique_ptr<CFX_XMLNode> Clone() override;
+ CFX_XMLNode* Clone(CFX_XMLDocument* doc) override;
void Save(const RetainPtr<IFX_SeekableWriteStream>& pXMLStream) override;
bool IsOriginalXFAVersion() const;
diff --git a/core/fxcrt/xml/cfx_xmlinstruction_unittest.cpp b/core/fxcrt/xml/cfx_xmlinstruction_unittest.cpp
index c60d401303..0c43c59ccd 100644
--- a/core/fxcrt/xml/cfx_xmlinstruction_unittest.cpp
+++ b/core/fxcrt/xml/cfx_xmlinstruction_unittest.cpp
@@ -4,6 +4,7 @@
#include "core/fxcrt/xml/cfx_xmlinstruction.h"
#include "core/fxcrt/cfx_memorystream.h"
+#include "core/fxcrt/xml/cfx_xmldocument.h"
#include "core/fxcrt/xml/cfx_xmlelement.h"
#include "core/fxcrt/xml/cfx_xmlparser.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -41,15 +42,17 @@ TEST(CFX_XMLInstructionTest, TargetData) {
}
TEST(CFX_XMLInstructionTest, Clone) {
+ CFX_XMLDocument doc;
+
CFX_XMLInstruction node(L"acrobat");
node.AppendData(L"firstString");
node.AppendData(L"secondString");
- auto clone = node.Clone();
+ CFX_XMLNode* clone = node.Clone(&doc);
EXPECT_TRUE(clone != nullptr);
ASSERT_EQ(FX_XMLNODE_Instruction, clone->GetType());
- CFX_XMLInstruction* inst = static_cast<CFX_XMLInstruction*>(clone.get());
+ CFX_XMLInstruction* inst = static_cast<CFX_XMLInstruction*>(clone);
EXPECT_TRUE(inst->IsAcrobat());
@@ -87,14 +90,16 @@ TEST(CFX_XMLInstructionTest, ParseAndReSave) {
reinterpret_cast<uint8_t*>(const_cast<char*>(input)), strlen(input),
false);
- CFX_XMLElement root(L"root");
- CFX_XMLParser parser(&root, in_stream);
- ASSERT_TRUE(parser.Parse());
- ASSERT_TRUE(root.GetFirstChild() != nullptr);
- ASSERT_EQ(FX_XMLNODE_Instruction, root.GetFirstChild()->GetType());
+ CFX_XMLParser parser(in_stream);
+ std::unique_ptr<CFX_XMLDocument> doc = parser.Parse();
+ ASSERT_TRUE(doc != nullptr);
+
+ CFX_XMLElement* root = doc->GetRoot();
+ ASSERT_TRUE(root->GetFirstChild() != nullptr);
+ ASSERT_EQ(FX_XMLNODE_Instruction, root->GetFirstChild()->GetType());
CFX_XMLInstruction* node =
- static_cast<CFX_XMLInstruction*>(root.GetFirstChild());
+ static_cast<CFX_XMLInstruction*>(root->GetFirstChild());
ASSERT_TRUE(node != nullptr);
EXPECT_TRUE(node->IsAcrobat());
@@ -109,3 +114,49 @@ TEST(CFX_XMLInstructionTest, ParseAndReSave) {
"<?acrobat http://www.xfa.org/schema/xfa-template/3.3/ Display:1 ?>\n",
out_stream->ToString());
}
+
+TEST(CFX_XMLInstructionTest, ParseAndReSaveInnerInstruction) {
+ const char* input =
+ "<node>\n"
+ "<?acrobat http://www.xfa.org/schema/xfa-template/3.3/ Display:1 ?>\n"
+ "</node>";
+
+ auto in_stream = pdfium::MakeRetain<CFX_MemoryStream>(
+ reinterpret_cast<uint8_t*>(const_cast<char*>(input)), strlen(input),
+ false);
+
+ CFX_XMLParser parser(in_stream);
+ std::unique_ptr<CFX_XMLDocument> doc = parser.Parse();
+ ASSERT_TRUE(doc != nullptr);
+
+ CFX_XMLElement* root = doc->GetRoot();
+ ASSERT_TRUE(root->GetFirstChild() != nullptr);
+ ASSERT_TRUE(root->GetFirstChild()->GetType() == FX_XMLNODE_Element);
+
+ CFX_XMLElement* node = static_cast<CFX_XMLElement*>(root->GetFirstChild());
+ EXPECT_EQ(L"node", node->GetName());
+
+ CFX_XMLInstruction* instruction = nullptr;
+ for (auto* elem = node->GetFirstChild(); elem;
+ elem = elem->GetNextSibling()) {
+ if (elem->GetType() == FX_XMLNODE_Instruction) {
+ instruction = static_cast<CFX_XMLInstruction*>(elem);
+ break;
+ }
+ }
+ ASSERT_TRUE(instruction != nullptr);
+ EXPECT_TRUE(instruction->IsAcrobat());
+
+ auto& data = instruction->GetTargetData();
+ ASSERT_EQ(2U, data.size());
+ EXPECT_EQ(L"http://www.xfa.org/schema/xfa-template/3.3/", data[0]);
+ EXPECT_EQ(L"Display:1", data[1]);
+
+ auto out_stream = pdfium::MakeRetain<StringWriteStream>();
+ node->Save(out_stream);
+ EXPECT_EQ(
+ "<node>\n\n"
+ "<?acrobat http://www.xfa.org/schema/xfa-template/3.3/ Display:1 ?>\n\n"
+ "</node>\n",
+ out_stream->ToString());
+}
diff --git a/core/fxcrt/xml/cfx_xmlnode.cpp b/core/fxcrt/xml/cfx_xmlnode.cpp
index 088cbf367c..c8fea23bda 100644
--- a/core/fxcrt/xml/cfx_xmlnode.cpp
+++ b/core/fxcrt/xml/cfx_xmlnode.cpp
@@ -17,38 +17,26 @@
CFX_XMLNode::CFX_XMLNode() = default;
-CFX_XMLNode::~CFX_XMLNode() {
- DeleteChildren();
-}
+CFX_XMLNode::~CFX_XMLNode() = default;
void CFX_XMLNode::DeleteChildren() {
- CFX_XMLNode* child = last_child_.Get();
- // Clear last child early as it will have been deleted already.
- last_child_ = nullptr;
- while (child) {
- child = child->prev_sibling_.Get();
- if (child) {
- if (child->next_sibling_) {
- child->next_sibling_->prev_sibling_ = nullptr;
- child->next_sibling_->parent_ = nullptr;
- }
-
- child->next_sibling_ = nullptr;
- }
- }
- if (first_child_) {
- first_child_->next_sibling_ = nullptr;
+ while (first_child_) {
first_child_->parent_ = nullptr;
+ first_child_->prev_sibling_ = nullptr;
+
+ CFX_XMLNode* child = first_child_;
+ first_child_ = child->next_sibling_;
+
+ child->next_sibling_ = nullptr;
}
- first_child_ = nullptr;
+ last_child_ = nullptr;
}
-void CFX_XMLNode::AppendChild(std::unique_ptr<CFX_XMLNode> pNode) {
- InsertChildNode(std::move(pNode), -1);
+void CFX_XMLNode::AppendChild(CFX_XMLNode* pNode) {
+ InsertChildNode(pNode, -1);
}
-void CFX_XMLNode::InsertChildNode(std::unique_ptr<CFX_XMLNode> pNode,
- int32_t index) {
+void CFX_XMLNode::InsertChildNode(CFX_XMLNode* pNode, int32_t index) {
ASSERT(!pNode->parent_);
pNode->parent_ = this;
@@ -56,36 +44,36 @@ void CFX_XMLNode::InsertChildNode(std::unique_ptr<CFX_XMLNode> pNode,
if (!first_child_) {
ASSERT(!last_child_);
- first_child_ = std::move(pNode);
- last_child_ = first_child_.get();
+ first_child_ = pNode;
+ last_child_ = first_child_;
first_child_->prev_sibling_ = nullptr;
first_child_->next_sibling_ = nullptr;
return;
}
if (index == 0) {
- first_child_->prev_sibling_ = pNode.get();
- pNode->next_sibling_ = std::move(first_child_);
+ first_child_->prev_sibling_ = pNode;
+ pNode->next_sibling_ = first_child_;
pNode->prev_sibling_ = nullptr;
- first_child_ = std::move(pNode);
+ first_child_ = pNode;
return;
}
int32_t iCount = 0;
- CFX_XMLNode* pFind = first_child_.get();
+ CFX_XMLNode* pFind = first_child_;
// Note, negative indexes, and indexes after the end of the list will result
// in appending to the list.
while (++iCount != index && pFind->next_sibling_)
- pFind = pFind->next_sibling_.get();
+ pFind = pFind->next_sibling_;
pNode->prev_sibling_ = pFind;
if (pFind->next_sibling_)
- pFind->next_sibling_->prev_sibling_ = pNode.get();
- pNode->next_sibling_ = std::move(pFind->next_sibling_);
+ pFind->next_sibling_->prev_sibling_ = pNode;
+ pNode->next_sibling_ = pFind->next_sibling_;
- pFind->next_sibling_ = std::move(pNode);
- if (pFind == last_child_.Get())
- last_child_ = pFind->next_sibling_.get();
+ pFind->next_sibling_ = pNode;
+ if (pFind == last_child_)
+ last_child_ = pFind->next_sibling_;
}
void CFX_XMLNode::RemoveChildNode(CFX_XMLNode* pNode) {
@@ -95,35 +83,25 @@ void CFX_XMLNode::RemoveChildNode(CFX_XMLNode* pNode) {
if (pNode->GetParent() != this)
return;
- if (first_child_.get() == pNode) {
- first_child_.release();
- first_child_ = std::move(pNode->next_sibling_);
- if (first_child_) {
- first_child_->prev_sibling_ = nullptr;
-
- if (first_child_->next_sibling_)
- first_child_->next_sibling_->prev_sibling_ = first_child_.get();
- }
- } else {
- CFX_XMLNode* prev = pNode->prev_sibling_.Get();
- prev->next_sibling_.release(); // Release pNode
- prev->next_sibling_ = std::move(pNode->next_sibling_);
-
- if (prev->next_sibling_)
- prev->next_sibling_->prev_sibling_ = prev;
- }
+ if (first_child_ == pNode)
+ first_child_ = pNode->next_sibling_;
+ if (last_child_ == pNode)
+ last_child_ = pNode->prev_sibling_;
- if (last_child_.Get() == pNode)
- last_child_ = pNode->prev_sibling_.Get();
+ if (pNode->prev_sibling_)
+ pNode->prev_sibling_->next_sibling_ = pNode->next_sibling_;
+ if (pNode->next_sibling_)
+ pNode->next_sibling_->prev_sibling_ = pNode->prev_sibling_;
pNode->parent_ = nullptr;
pNode->prev_sibling_ = nullptr;
+ pNode->next_sibling_ = nullptr;
}
CFX_XMLNode* CFX_XMLNode::GetRoot() {
CFX_XMLNode* pParent = this;
while (pParent->parent_)
- pParent = pParent->parent_.Get();
+ pParent = pParent->parent_;
return pParent;
}
diff --git a/core/fxcrt/xml/cfx_xmlnode.h b/core/fxcrt/xml/cfx_xmlnode.h
index 4c98a3b51a..95dc0acce9 100644
--- a/core/fxcrt/xml/cfx_xmlnode.h
+++ b/core/fxcrt/xml/cfx_xmlnode.h
@@ -19,39 +19,41 @@ enum FX_XMLNODETYPE {
FX_XMLNODE_CharData,
};
+class CFX_XMLDocument;
+
class CFX_XMLNode {
public:
CFX_XMLNode();
virtual ~CFX_XMLNode();
virtual FX_XMLNODETYPE GetType() const = 0;
- virtual std::unique_ptr<CFX_XMLNode> Clone() = 0;
+ virtual CFX_XMLNode* Clone(CFX_XMLDocument* doc) = 0;
virtual void Save(const RetainPtr<IFX_SeekableWriteStream>& pXMLStream) = 0;
CFX_XMLNode* GetRoot();
- CFX_XMLNode* GetParent() const { return parent_.Get(); }
- CFX_XMLNode* GetFirstChild() const { return first_child_.get(); }
- CFX_XMLNode* GetNextSibling() const { return next_sibling_.get(); }
+ CFX_XMLNode* GetParent() const { return parent_; }
+ CFX_XMLNode* GetFirstChild() const { return first_child_; }
+ CFX_XMLNode* GetNextSibling() const { return next_sibling_; }
- void AppendChild(std::unique_ptr<CFX_XMLNode> pNode);
- void InsertChildNode(std::unique_ptr<CFX_XMLNode> pNode, int32_t index);
+ void AppendChild(CFX_XMLNode* pNode);
+ void InsertChildNode(CFX_XMLNode* pNode, int32_t index);
void RemoveChildNode(CFX_XMLNode* pNode);
void DeleteChildren();
- CFX_XMLNode* GetLastChildForTesting() const { return last_child_.Get(); }
- CFX_XMLNode* GetPrevSiblingForTesting() const { return prev_sibling_.Get(); }
+ CFX_XMLNode* GetLastChildForTesting() const { return last_child_; }
+ CFX_XMLNode* GetPrevSiblingForTesting() const { return prev_sibling_; }
protected:
WideString EncodeEntities(const WideString& value);
private:
- // A node owns its first child and it owns its next sibling. The rest
- // are unowned pointers.
- UnownedPtr<CFX_XMLNode> parent_;
- UnownedPtr<CFX_XMLNode> last_child_;
- UnownedPtr<CFX_XMLNode> prev_sibling_;
- std::unique_ptr<CFX_XMLNode> first_child_;
- std::unique_ptr<CFX_XMLNode> next_sibling_;
+ // The nodes are owned by the XML document. We do not know what order the
+ // nodes will be destroyed in so they can not be UnownedPtrs.
+ CFX_XMLNode* parent_ = nullptr;
+ CFX_XMLNode* first_child_ = nullptr;
+ CFX_XMLNode* last_child_ = nullptr;
+ CFX_XMLNode* next_sibling_ = nullptr;
+ CFX_XMLNode* prev_sibling_ = nullptr;
};
#endif // CORE_FXCRT_XML_CFX_XMLNODE_H_
diff --git a/core/fxcrt/xml/cfx_xmlnode_unittest.cpp b/core/fxcrt/xml/cfx_xmlnode_unittest.cpp
index 1c69069942..ec56603a58 100644
--- a/core/fxcrt/xml/cfx_xmlnode_unittest.cpp
+++ b/core/fxcrt/xml/cfx_xmlnode_unittest.cpp
@@ -2,274 +2,227 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include <utility>
-
#include "core/fxcrt/xml/cfx_xmlelement.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/test_support.h"
-#include "third_party/base/ptr_util.h"
TEST(CFX_XMLNodeTest, GetParent) {
- auto node1 = pdfium::MakeUnique<CFX_XMLElement>(L"node");
- auto child2 = pdfium::MakeUnique<CFX_XMLElement>(L"node2");
- auto child3 = pdfium::MakeUnique<CFX_XMLElement>(L"node3");
-
- CFX_XMLElement* node2 = child2.get();
- CFX_XMLElement* node3 = child3.get();
+ CFX_XMLElement node1(L"node");
+ CFX_XMLElement node2(L"node2");
+ CFX_XMLElement node3(L"node3");
- node1->AppendChild(std::move(child2));
- node2->AppendChild(std::move(child3));
+ node1.AppendChild(&node2);
+ node2.AppendChild(&node3);
- EXPECT_EQ(nullptr, node1->GetParent());
- EXPECT_EQ(node1.get(), node2->GetParent());
- EXPECT_EQ(node2, node3->GetParent());
+ EXPECT_EQ(nullptr, node1.GetParent());
+ EXPECT_EQ(&node1, node2.GetParent());
+ EXPECT_EQ(&node2, node3.GetParent());
}
TEST(CFX_XMLNodeTest, GetRoot) {
- auto node1 = pdfium::MakeUnique<CFX_XMLElement>(L"node");
- auto child2 = pdfium::MakeUnique<CFX_XMLElement>(L"node2");
- auto child3 = pdfium::MakeUnique<CFX_XMLElement>(L"node3");
+ CFX_XMLElement node1(L"node");
+ CFX_XMLElement node2(L"node2");
+ CFX_XMLElement node3(L"node3");
- CFX_XMLElement* node2 = child2.get();
- CFX_XMLElement* node3 = child3.get();
+ node1.AppendChild(&node2);
+ node2.AppendChild(&node3);
- node1->AppendChild(std::move(child2));
- node2->AppendChild(std::move(child3));
-
- EXPECT_EQ(node1.get(), node1->GetRoot());
- EXPECT_EQ(node1.get(), node2->GetRoot());
- EXPECT_EQ(node1.get(), node3->GetRoot());
+ EXPECT_EQ(&node1, node1.GetRoot());
+ EXPECT_EQ(&node1, node2.GetRoot());
+ EXPECT_EQ(&node1, node3.GetRoot());
}
TEST(CFX_XMLNodeTest, GetChildren) {
- auto node1 = pdfium::MakeUnique<CFX_XMLElement>(L"node");
- auto child2 = pdfium::MakeUnique<CFX_XMLElement>(L"node2");
- auto child3 = pdfium::MakeUnique<CFX_XMLElement>(L"node3");
- auto child4 = pdfium::MakeUnique<CFX_XMLElement>(L"node4");
-
- CFX_XMLElement* node2 = child2.get();
- CFX_XMLElement* node3 = child3.get();
- CFX_XMLElement* node4 = child4.get();
+ CFX_XMLElement node1(L"node");
+ CFX_XMLElement node2(L"node2");
+ CFX_XMLElement node3(L"node3");
+ CFX_XMLElement node4(L"node4");
- node1->AppendChild(std::move(child2));
- node1->AppendChild(std::move(child4));
- node2->AppendChild(std::move(child3));
+ node1.AppendChild(&node2);
+ node1.AppendChild(&node4);
+ node2.AppendChild(&node3);
- EXPECT_EQ(node2, node1->GetFirstChild());
+ EXPECT_EQ(&node2, node1.GetFirstChild());
- EXPECT_EQ(node4, node2->GetNextSibling());
- EXPECT_EQ(node3, node2->GetFirstChild());
+ EXPECT_EQ(&node4, node2.GetNextSibling());
+ EXPECT_EQ(&node3, node2.GetFirstChild());
- EXPECT_TRUE(node3->GetNextSibling() == nullptr);
- EXPECT_TRUE(node3->GetFirstChild() == nullptr);
+ EXPECT_TRUE(node3.GetNextSibling() == nullptr);
+ EXPECT_TRUE(node3.GetFirstChild() == nullptr);
- EXPECT_TRUE(node4->GetNextSibling() == nullptr);
- EXPECT_TRUE(node4->GetFirstChild() == nullptr);
+ EXPECT_TRUE(node4.GetNextSibling() == nullptr);
+ EXPECT_TRUE(node4.GetFirstChild() == nullptr);
}
TEST(CFX_XMLNodeTest, DeleteChildren) {
- auto node1 = pdfium::MakeUnique<CFX_XMLElement>(L"node");
- auto child2 = pdfium::MakeUnique<CFX_XMLElement>(L"node2");
- auto child3 = pdfium::MakeUnique<CFX_XMLElement>(L"node3");
- auto child4 = pdfium::MakeUnique<CFX_XMLElement>(L"node4");
-
- CFX_XMLElement* node2 = child2.get();
- // CFX_XMLElement* node3 = child3.get();
- // CFX_XMLElement* node4 = child4.get();
-
- node1->AppendChild(std::move(child2));
- node1->AppendChild(std::move(child4));
- node2->AppendChild(std::move(child3));
-
- node1->DeleteChildren();
- EXPECT_TRUE(node1->GetFirstChild() == nullptr);
- EXPECT_TRUE(node1->GetLastChildForTesting() == nullptr);
+ CFX_XMLElement node1(L"node");
+ CFX_XMLElement node2(L"node2");
+ CFX_XMLElement node3(L"node3");
+ CFX_XMLElement node4(L"node4");
- // TODO(dsinclair): This isn't true currently but will be true when
- // we own the nodes in an XML document. (Currently nodes are unique_ptrs
- // so the objects have been deleted by this point.)
+ node1.AppendChild(&node2);
+ node1.AppendChild(&node4);
+ node2.AppendChild(&node3);
- // EXPECT_TRUE(node2->GetParent() == nullptr);
- // EXPECT_TRUE(node4->GetParent() == nullptr);
+ node1.DeleteChildren();
+ EXPECT_TRUE(node1.GetFirstChild() == nullptr);
+ EXPECT_TRUE(node2.GetParent() == nullptr);
+ EXPECT_TRUE(node4.GetParent() == nullptr);
- // // node2 and node4 should no longer be siblings.
- // EXPECT_TRUE(node2->GetNextSibling() == nullptr);
- // EXPECT_TRUE(node4->GetPrevSiblingForTesting() == nullptr);
+ // node2 and node4 should no longer be siblings.
+ EXPECT_TRUE(node2.GetNextSibling() == nullptr);
+ EXPECT_TRUE(node4.GetPrevSiblingForTesting() == nullptr);
// Deleting children doesn't change deleted substructure
- // EXPECT_EQ(node3, node2->GetFirstChild());
- // EXPECT_TRUE(node3->GetParent() == node2);
+ EXPECT_EQ(&node3, node2.GetFirstChild());
+ EXPECT_TRUE(node3.GetParent() == &node2);
}
TEST(CFX_XMLNodeTest, AddingChildren) {
- auto node1 = pdfium::MakeUnique<CFX_XMLElement>(L"node");
- auto child2 = pdfium::MakeUnique<CFX_XMLElement>(L"node2");
- auto child3 = pdfium::MakeUnique<CFX_XMLElement>(L"node3");
- auto child4 = pdfium::MakeUnique<CFX_XMLElement>(L"node4");
- auto child5 = pdfium::MakeUnique<CFX_XMLElement>(L"node5");
+ CFX_XMLElement node1(L"node");
+ CFX_XMLElement node2(L"node2");
+ CFX_XMLElement node3(L"node3");
- CFX_XMLElement* node2 = child2.get();
- CFX_XMLElement* node3 = child3.get();
- CFX_XMLElement* node4 = child4.get();
- CFX_XMLElement* node5 = child5.get();
+ node1.AppendChild(&node2);
+ node1.AppendChild(&node3);
- node1->AppendChild(std::move(child2));
- node1->AppendChild(std::move(child3));
+ EXPECT_EQ(&node1, node2.GetParent());
+ EXPECT_EQ(&node1, node3.GetParent());
- EXPECT_EQ(node1.get(), node2->GetParent());
- EXPECT_EQ(node1.get(), node3->GetParent());
-
- EXPECT_EQ(node2, node1->GetFirstChild());
- EXPECT_EQ(node3, node2->GetNextSibling());
- EXPECT_TRUE(node3->GetNextSibling() == nullptr);
+ EXPECT_EQ(&node2, node1.GetFirstChild());
+ EXPECT_EQ(&node3, node2.GetNextSibling());
+ EXPECT_TRUE(node3.GetNextSibling() == nullptr);
// Insert to negative appends.
- node1->InsertChildNode(std::move(child4), -1);
- EXPECT_EQ(node1.get(), node4->GetParent());
- EXPECT_EQ(node4, node3->GetNextSibling());
- EXPECT_TRUE(node4->GetNextSibling() == nullptr);
-
- node1->InsertChildNode(std::move(child5), 1);
- EXPECT_EQ(node1.get(), node5->GetParent());
- EXPECT_EQ(node2, node1->GetFirstChild());
- EXPECT_EQ(node5, node2->GetNextSibling());
- EXPECT_EQ(node3, node5->GetNextSibling());
- EXPECT_EQ(node4, node3->GetNextSibling());
- EXPECT_TRUE(node4->GetNextSibling() == nullptr);
+ CFX_XMLElement node4(L"node4");
+ node1.InsertChildNode(&node4, -1);
+ EXPECT_EQ(&node1, node4.GetParent());
+ EXPECT_EQ(&node4, node3.GetNextSibling());
+ EXPECT_TRUE(node4.GetNextSibling() == nullptr);
+
+ CFX_XMLElement node5(L"node5");
+ node1.InsertChildNode(&node5, 1);
+ EXPECT_EQ(&node1, node5.GetParent());
+ EXPECT_EQ(&node2, node1.GetFirstChild());
+ EXPECT_EQ(&node5, node2.GetNextSibling());
+ EXPECT_EQ(&node3, node5.GetNextSibling());
+ EXPECT_EQ(&node4, node3.GetNextSibling());
+ EXPECT_TRUE(node4.GetNextSibling() == nullptr);
+}
+
+#ifndef NDEBUG
+TEST(CFX_XMLNodeTest, DuplicateInsertOfNode) {
+ CFX_XMLElement node1(L"node");
+ CFX_XMLElement node2(L"node2");
+
+ node1.AppendChild(&node2);
+ EXPECT_DEATH(node1.AppendChild(&node2), "");
}
+#endif // NDEBUG
TEST(CFX_XMLNodeTest, RemovingMiddleChild) {
- auto node1 = pdfium::MakeUnique<CFX_XMLElement>(L"node");
- auto child2 = pdfium::MakeUnique<CFX_XMLElement>(L"node2");
- auto child3 = pdfium::MakeUnique<CFX_XMLElement>(L"node3");
- auto child4 = pdfium::MakeUnique<CFX_XMLElement>(L"node4");
-
- CFX_XMLElement* node2 = child2.get();
- CFX_XMLElement* node3 = child3.get();
- CFX_XMLElement* node4 = child4.get();
-
- node1->AppendChild(std::move(child2));
- node1->AppendChild(std::move(child3));
- node1->AppendChild(std::move(child4));
-
- EXPECT_EQ(node2, node1->GetFirstChild());
- EXPECT_EQ(node3, node2->GetNextSibling());
- EXPECT_EQ(node4, node3->GetNextSibling());
- EXPECT_TRUE(node4->GetNextSibling() == nullptr);
-
- node1->RemoveChildNode(node3);
- // Node is released by parent, so need to take ownership
- child3 = pdfium::WrapUnique(node3);
-
- EXPECT_TRUE(node3->GetParent() == nullptr);
- EXPECT_TRUE(node3->GetNextSibling() == nullptr);
- EXPECT_TRUE(node3->GetPrevSiblingForTesting() == nullptr);
-
- EXPECT_EQ(node2, node1->GetFirstChild());
- EXPECT_EQ(node4, node2->GetNextSibling());
- EXPECT_EQ(node2, node4->GetPrevSiblingForTesting());
- EXPECT_TRUE(node4->GetNextSibling() == nullptr);
+ CFX_XMLElement node1(L"node1");
+ CFX_XMLElement node2(L"node2");
+ CFX_XMLElement node3(L"node3");
+ CFX_XMLElement node4(L"node4");
+
+ node1.AppendChild(&node2);
+ node1.AppendChild(&node3);
+ node1.AppendChild(&node4);
+
+ EXPECT_EQ(&node2, node1.GetFirstChild());
+ EXPECT_EQ(&node3, node2.GetNextSibling());
+ EXPECT_EQ(&node4, node3.GetNextSibling());
+ EXPECT_TRUE(node4.GetNextSibling() == nullptr);
+
+ node1.RemoveChildNode(&node3);
+ EXPECT_TRUE(node3.GetParent() == nullptr);
+ EXPECT_TRUE(node3.GetNextSibling() == nullptr);
+ EXPECT_TRUE(node3.GetPrevSiblingForTesting() == nullptr);
+
+ EXPECT_EQ(&node2, node1.GetFirstChild());
+ EXPECT_EQ(&node4, node2.GetNextSibling());
+ EXPECT_EQ(&node2, node4.GetPrevSiblingForTesting());
+ EXPECT_TRUE(node4.GetNextSibling() == nullptr);
}
TEST(CFX_XMLNodeTest, RemovingFirstChild) {
- auto node1 = pdfium::MakeUnique<CFX_XMLElement>(L"node");
- auto child2 = pdfium::MakeUnique<CFX_XMLElement>(L"node2");
- auto child3 = pdfium::MakeUnique<CFX_XMLElement>(L"node3");
- auto child4 = pdfium::MakeUnique<CFX_XMLElement>(L"node4");
-
- CFX_XMLElement* node2 = child2.get();
- CFX_XMLElement* node3 = child3.get();
- CFX_XMLElement* node4 = child4.get();
-
- node1->AppendChild(std::move(child2));
- node1->AppendChild(std::move(child3));
- node1->AppendChild(std::move(child4));
-
- EXPECT_EQ(node2, node1->GetFirstChild());
- EXPECT_EQ(node3, node2->GetNextSibling());
- EXPECT_EQ(node4, node3->GetNextSibling());
- EXPECT_TRUE(node4->GetNextSibling() == nullptr);
-
- node1->RemoveChildNode(node2);
- // Node is released by parent, so need to take ownership
- child2 = pdfium::WrapUnique(node2);
-
- EXPECT_TRUE(node2->GetParent() == nullptr);
- EXPECT_TRUE(node2->GetNextSibling() == nullptr);
- EXPECT_TRUE(node2->GetPrevSiblingForTesting() == nullptr);
-
- EXPECT_EQ(node3, node1->GetFirstChild());
- EXPECT_TRUE(node3->GetPrevSiblingForTesting() == nullptr);
- EXPECT_EQ(node4, node3->GetNextSibling());
- EXPECT_TRUE(node4->GetNextSibling() == nullptr);
+ CFX_XMLElement node1(L"node1");
+ CFX_XMLElement node2(L"node2");
+ CFX_XMLElement node3(L"node3");
+ CFX_XMLElement node4(L"node4");
+
+ node1.AppendChild(&node2);
+ node1.AppendChild(&node3);
+ node1.AppendChild(&node4);
+
+ EXPECT_EQ(&node2, node1.GetFirstChild());
+ EXPECT_EQ(&node3, node2.GetNextSibling());
+ EXPECT_EQ(&node4, node3.GetNextSibling());
+ EXPECT_TRUE(node4.GetNextSibling() == nullptr);
+
+ node1.RemoveChildNode(&node2);
+ EXPECT_TRUE(node2.GetParent() == nullptr);
+ EXPECT_TRUE(node2.GetNextSibling() == nullptr);
+ EXPECT_TRUE(node2.GetPrevSiblingForTesting() == nullptr);
+
+ EXPECT_EQ(&node3, node1.GetFirstChild());
+ EXPECT_TRUE(node3.GetPrevSiblingForTesting() == nullptr);
+ EXPECT_EQ(&node4, node3.GetNextSibling());
+ EXPECT_TRUE(node4.GetNextSibling() == nullptr);
}
TEST(CFX_XMLNodeTest, RemovingLastChild) {
- auto node1 = pdfium::MakeUnique<CFX_XMLElement>(L"node");
- auto child2 = pdfium::MakeUnique<CFX_XMLElement>(L"node2");
- auto child3 = pdfium::MakeUnique<CFX_XMLElement>(L"node3");
- auto child4 = pdfium::MakeUnique<CFX_XMLElement>(L"node4");
-
- CFX_XMLElement* node2 = child2.get();
- CFX_XMLElement* node3 = child3.get();
- CFX_XMLElement* node4 = child4.get();
-
- node1->AppendChild(std::move(child2));
- node1->AppendChild(std::move(child3));
- node1->AppendChild(std::move(child4));
-
- EXPECT_EQ(node2, node1->GetFirstChild());
- EXPECT_EQ(node3, node2->GetNextSibling());
- EXPECT_EQ(node4, node3->GetNextSibling());
- EXPECT_TRUE(node4->GetNextSibling() == nullptr);
-
- node1->RemoveChildNode(node4);
- // Node is released by parent, so need to take ownership
- child4 = pdfium::WrapUnique(node4);
-
- EXPECT_TRUE(node4->GetParent() == nullptr);
- EXPECT_TRUE(node4->GetNextSibling() == nullptr);
- EXPECT_TRUE(node4->GetPrevSiblingForTesting() == nullptr);
-
- EXPECT_EQ(node2, node1->GetFirstChild());
- EXPECT_EQ(node3, node2->GetNextSibling());
- EXPECT_TRUE(node3->GetNextSibling() == nullptr);
+ CFX_XMLElement node1(L"node1");
+ CFX_XMLElement node2(L"node2");
+ CFX_XMLElement node3(L"node3");
+ CFX_XMLElement node4(L"node4");
+
+ node1.AppendChild(&node2);
+ node1.AppendChild(&node3);
+ node1.AppendChild(&node4);
+
+ EXPECT_EQ(&node2, node1.GetFirstChild());
+ EXPECT_EQ(&node3, node2.GetNextSibling());
+ EXPECT_EQ(&node4, node3.GetNextSibling());
+ EXPECT_TRUE(node4.GetNextSibling() == nullptr);
+
+ node1.RemoveChildNode(&node4);
+ EXPECT_TRUE(node4.GetParent() == nullptr);
+ EXPECT_TRUE(node4.GetNextSibling() == nullptr);
+ EXPECT_TRUE(node4.GetPrevSiblingForTesting() == nullptr);
+
+ EXPECT_EQ(&node2, node1.GetFirstChild());
+ EXPECT_EQ(&node3, node2.GetNextSibling());
+ EXPECT_TRUE(node3.GetNextSibling() == nullptr);
}
TEST(CFX_XMLNodeTest, RemovingOnlyChild) {
- auto node1 = pdfium::MakeUnique<CFX_XMLElement>(L"node");
- auto child2 = pdfium::MakeUnique<CFX_XMLElement>(L"node2");
+ CFX_XMLElement node1(L"node1");
+ CFX_XMLElement node2(L"node2");
- CFX_XMLElement* node2 = child2.get();
+ node1.AppendChild(&node2);
- node1->AppendChild(std::move(child2));
+ EXPECT_EQ(&node2, node1.GetFirstChild());
+ EXPECT_TRUE(node2.GetNextSibling() == nullptr);
- EXPECT_EQ(node2, node1->GetFirstChild());
- EXPECT_TRUE(node2->GetNextSibling() == nullptr);
+ node1.RemoveChildNode(&node2);
+ EXPECT_TRUE(node2.GetParent() == nullptr);
- node1->RemoveChildNode(node2);
- // Node is released by parent, so need to take ownership
- child2 = pdfium::WrapUnique(node2);
-
- EXPECT_TRUE(node2->GetParent() == nullptr);
-
- EXPECT_TRUE(node1->GetFirstChild() == nullptr);
- EXPECT_TRUE(node2->GetNextSibling() == nullptr);
- EXPECT_TRUE(node2->GetPrevSiblingForTesting() == nullptr);
+ EXPECT_TRUE(node1.GetFirstChild() == nullptr);
+ EXPECT_TRUE(node2.GetNextSibling() == nullptr);
+ EXPECT_TRUE(node2.GetPrevSiblingForTesting() == nullptr);
}
TEST(CFX_XMLNodeTest, RemoveMissingChild) {
- auto node1 = pdfium::MakeUnique<CFX_XMLElement>(L"node");
- auto child2 = pdfium::MakeUnique<CFX_XMLElement>(L"node2");
- auto child3 = pdfium::MakeUnique<CFX_XMLElement>(L"node3");
-
- CFX_XMLElement* node2 = child2.get();
- CFX_XMLElement* node3 = child3.get();
+ CFX_XMLElement node1(L"node1");
+ CFX_XMLElement node2(L"node2");
+ CFX_XMLElement node3(L"node3");
- node1->AppendChild(std::move(child2));
- node1->RemoveChildNode(node3);
+ node1.AppendChild(&node2);
+ node1.RemoveChildNode(&node3);
- EXPECT_TRUE(node3->GetParent() == nullptr);
- EXPECT_EQ(node2, node1->GetFirstChild());
- EXPECT_TRUE(node2->GetNextSibling() == nullptr);
+ EXPECT_TRUE(node3.GetParent() == nullptr);
+ EXPECT_EQ(&node2, node1.GetFirstChild());
+ EXPECT_TRUE(node2.GetNextSibling() == nullptr);
}
diff --git a/core/fxcrt/xml/cfx_xmlparser.cpp b/core/fxcrt/xml/cfx_xmlparser.cpp
index c7a81afc16..b7dbd19eab 100644
--- a/core/fxcrt/xml/cfx_xmlparser.cpp
+++ b/core/fxcrt/xml/cfx_xmlparser.cpp
@@ -16,6 +16,7 @@
#include "core/fxcrt/fx_extension.h"
#include "core/fxcrt/fx_safe_types.h"
#include "core/fxcrt/xml/cfx_xmlchardata.h"
+#include "core/fxcrt/xml/cfx_xmldocument.h"
#include "core/fxcrt/xml/cfx_xmlelement.h"
#include "core/fxcrt/xml/cfx_xmlinstruction.h"
#include "core/fxcrt/xml/cfx_xmlnode.h"
@@ -58,10 +59,7 @@ bool CFX_XMLParser::IsXMLNameChar(wchar_t ch, bool bFirstChar) {
(!bFirstChar || it->bStartChar);
}
-CFX_XMLParser::CFX_XMLParser(CFX_XMLNode* pParent,
- const RetainPtr<IFX_SeekableReadStream>& pStream)
- : m_pParent(pParent) {
- ASSERT(m_pParent);
+CFX_XMLParser::CFX_XMLParser(const RetainPtr<IFX_SeekableReadStream>& pStream) {
ASSERT(pStream);
auto proxy = pdfium::MakeRetain<CFX_SeekableStreamProxy>(pStream);
@@ -89,56 +87,51 @@ CFX_XMLParser::CFX_XMLParser(CFX_XMLNode* pParent,
CFX_XMLParser::~CFX_XMLParser() = default;
-bool CFX_XMLParser::Parse() {
+std::unique_ptr<CFX_XMLDocument> CFX_XMLParser::Parse() {
+ auto doc = pdfium::MakeUnique<CFX_XMLDocument>();
+ current_node_ = doc->GetRoot();
+
int32_t iCount = 0;
while (true) {
FX_XmlSyntaxResult result = DoSyntaxParse();
if (result == FX_XmlSyntaxResult::Error)
- return false;
+ return nullptr;
if (result == FX_XmlSyntaxResult::EndOfString)
break;
switch (result) {
case FX_XmlSyntaxResult::InstructionClose:
- if (m_pChild && m_pChild->GetType() != FX_XMLNODE_Instruction)
- return false;
-
- m_pChild = m_pParent;
+ if (current_node_ && current_node_->GetType() == FX_XMLNODE_Instruction)
+ current_node_ = current_node_->GetParent();
break;
case FX_XmlSyntaxResult::ElementClose: {
- if (m_pChild->GetType() != FX_XMLNODE_Element)
- return false;
+ if (current_node_->GetType() != FX_XMLNODE_Element)
+ return nullptr;
WideString element_name = GetTextData();
if (element_name.GetLength() > 0 &&
- element_name != static_cast<CFX_XMLElement*>(m_pChild)->GetName()) {
- return false;
+ element_name !=
+ static_cast<CFX_XMLElement*>(current_node_)->GetName()) {
+ return nullptr;
}
- if (!m_pChild || !m_pChild->GetParent())
- return false;
-
- m_pParent = m_pChild->GetParent();
- m_pChild = m_pParent;
+ current_node_ = current_node_->GetParent();
iCount++;
break;
}
case FX_XmlSyntaxResult::TargetName: {
WideString target_name = GetTextData();
if (target_name == L"originalXFAVersion" || target_name == L"acrobat") {
- auto child = pdfium::MakeUnique<CFX_XMLInstruction>(target_name);
- m_pChild = child.get();
- m_pParent->AppendChild(std::move(child));
- } else {
- m_pChild = nullptr;
+ auto* node = doc->CreateNode<CFX_XMLInstruction>(target_name);
+ current_node_->AppendChild(node);
+ current_node_ = node;
}
break;
}
case FX_XmlSyntaxResult::TagName: {
- auto child = pdfium::MakeUnique<CFX_XMLElement>(GetTextData());
- m_pChild = child.get();
- m_pParent->AppendChild(std::move(child));
- m_pParent = m_pChild;
+ auto* child = doc->CreateNode<CFX_XMLElement>(GetTextData());
+ current_node_->AppendChild(child);
+ current_node_ = child;
break;
}
case FX_XmlSyntaxResult::AttriName: {
@@ -146,35 +139,29 @@ bool CFX_XMLParser::Parse() {
break;
}
case FX_XmlSyntaxResult::AttriValue:
- if (m_pChild && m_pChild->GetType() == FX_XMLNODE_Element) {
- static_cast<CFX_XMLElement*>(m_pChild)->SetAttribute(
- current_attribute_name_, GetTextData());
+ if (current_node_ && current_node_->GetType() == FX_XMLNODE_Element) {
+ static_cast<CFX_XMLElement*>(current_node_)
+ ->SetAttribute(current_attribute_name_, GetTextData());
}
current_attribute_name_.clear();
break;
case FX_XmlSyntaxResult::Text: {
- auto child = pdfium::MakeUnique<CFX_XMLText>(GetTextData());
- m_pChild = child.get();
- m_pParent->AppendChild(std::move(child));
- m_pChild = m_pParent;
+ current_node_->AppendChild(doc->CreateNode<CFX_XMLText>(GetTextData()));
break;
}
case FX_XmlSyntaxResult::CData: {
- auto child = pdfium::MakeUnique<CFX_XMLCharData>(GetTextData());
- m_pChild = child.get();
- m_pParent->AppendChild(std::move(child));
- m_pChild = m_pParent;
+ current_node_->AppendChild(
+ doc->CreateNode<CFX_XMLCharData>(GetTextData()));
break;
}
case FX_XmlSyntaxResult::TargetData: {
WideString target_data = GetTextData();
- if (m_pChild) {
- if (m_pChild->GetType() != FX_XMLNODE_Instruction)
- return false;
-
- auto* instruction = static_cast<CFX_XMLInstruction*>(m_pChild);
- if (!target_data.IsEmpty())
- instruction->AppendData(target_data);
+ if (current_node_ &&
+ current_node_->GetType() == FX_XMLNODE_Instruction) {
+ if (target_data.IsEmpty())
+ break;
+ static_cast<CFX_XMLInstruction*>(current_node_)
+ ->AppendData(target_data);
}
break;
}
@@ -185,7 +172,7 @@ bool CFX_XMLParser::Parse() {
break;
}
}
- return !m_pParent || m_pParent->GetParent() ? false : GetStatus();
+ return doc;
}
FX_XmlSyntaxResult CFX_XMLParser::DoSyntaxParse() {
diff --git a/core/fxcrt/xml/cfx_xmlparser.h b/core/fxcrt/xml/cfx_xmlparser.h
index e2a2d5b30f..6bf1946402 100644
--- a/core/fxcrt/xml/cfx_xmlparser.h
+++ b/core/fxcrt/xml/cfx_xmlparser.h
@@ -15,6 +15,7 @@
#include "core/fxcrt/retain_ptr.h"
#include "core/fxcrt/xml/cfx_xmlnode.h"
+class CFX_XMLDocument;
class CFX_XMLElement;
class CFX_XMLNode;
class IFX_SeekableReadStream;
@@ -41,11 +42,10 @@ class CFX_XMLParser {
public:
static bool IsXMLNameChar(wchar_t ch, bool bFirstChar);
- CFX_XMLParser(CFX_XMLNode* pParent,
- const RetainPtr<IFX_SeekableReadStream>& pStream);
+ explicit CFX_XMLParser(const RetainPtr<IFX_SeekableReadStream>& pStream);
virtual ~CFX_XMLParser();
- bool Parse();
+ std::unique_ptr<CFX_XMLDocument> Parse();
protected:
FX_XmlSyntaxResult DoSyntaxParse();
@@ -74,8 +74,7 @@ class CFX_XMLParser {
void ParseTextChar(wchar_t ch);
bool GetStatus() const;
- CFX_XMLNode* m_pParent;
- CFX_XMLNode* m_pChild = nullptr;
+ CFX_XMLNode* current_node_ = nullptr;
WideString current_attribute_name_;
RetainPtr<IFX_SeekableReadStream> m_pStream;
FX_FILESIZE m_Start = 0; // Start position in m_Buffer
diff --git a/core/fxcrt/xml/cfx_xmlparser_unittest.cpp b/core/fxcrt/xml/cfx_xmlparser_unittest.cpp
index 73d6685dad..7ca242211d 100644
--- a/core/fxcrt/xml/cfx_xmlparser_unittest.cpp
+++ b/core/fxcrt/xml/cfx_xmlparser_unittest.cpp
@@ -8,7 +8,9 @@
#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_xmlinstruction.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/test_support.h"
#include "third_party/base/ptr_util.h"
@@ -17,9 +19,8 @@ namespace {
class CFX_XMLTestParser : public CFX_XMLParser {
public:
- CFX_XMLTestParser(CFX_XMLNode* pParent,
- const RetainPtr<IFX_SeekableStream>& pStream)
- : CFX_XMLParser(pParent, pStream) {}
+ explicit CFX_XMLTestParser(const RetainPtr<IFX_SeekableStream>& pStream)
+ : CFX_XMLParser(pStream) {}
~CFX_XMLTestParser() override = default;
@@ -52,9 +53,7 @@ TEST(CFX_XMLParserTest, CData) {
L" ";
auto stream = MakeProxy(input);
- auto root = pdfium::MakeUnique<CFX_XMLElement>(L"ROOT");
-
- CFX_XMLTestParser parser(root.get(), stream);
+ CFX_XMLTestParser parser(stream);
ASSERT_EQ(FX_XmlSyntaxResult::ElementOpen, parser.DoSyntaxParse());
ASSERT_EQ(FX_XmlSyntaxResult::TagName, parser.DoSyntaxParse());
ASSERT_EQ(L"script", parser.GetTextData());
@@ -98,9 +97,7 @@ TEST(CFX_XMLParserTest, CDataWithInnerScript) {
L" ";
auto stream = MakeProxy(input);
- auto root = pdfium::MakeUnique<CFX_XMLElement>(L"ROOT");
-
- CFX_XMLTestParser parser(root.get(), stream);
+ CFX_XMLTestParser parser(stream);
ASSERT_EQ(FX_XmlSyntaxResult::ElementOpen, parser.DoSyntaxParse());
ASSERT_EQ(FX_XmlSyntaxResult::TagName, parser.DoSyntaxParse());
ASSERT_EQ(L"script", parser.GetTextData());
@@ -133,9 +130,7 @@ TEST(CFX_XMLParserTest, ArrowBangArrow) {
"</script>";
auto stream = MakeProxy(input);
- auto root = pdfium::MakeUnique<CFX_XMLElement>(L"ROOT");
-
- CFX_XMLTestParser parser(root.get(), stream);
+ CFX_XMLTestParser parser(stream);
ASSERT_EQ(FX_XmlSyntaxResult::ElementOpen, parser.DoSyntaxParse());
ASSERT_EQ(FX_XmlSyntaxResult::TagName, parser.DoSyntaxParse());
@@ -166,9 +161,7 @@ TEST(CFX_XMLParserTest, ArrowBangBracketArrow) {
"</script>";
auto stream = MakeProxy(input);
- auto root = pdfium::MakeUnique<CFX_XMLElement>(L"ROOT");
-
- CFX_XMLTestParser parser(root.get(), stream);
+ CFX_XMLTestParser parser(stream);
ASSERT_EQ(FX_XmlSyntaxResult::ElementOpen, parser.DoSyntaxParse());
ASSERT_EQ(FX_XmlSyntaxResult::TagName, parser.DoSyntaxParse());
ASSERT_EQ(L"script", parser.GetTextData());
@@ -194,9 +187,7 @@ TEST(CFX_XMLParserTest, IncompleteCData) {
"</script>";
auto stream = MakeProxy(input);
- auto root = pdfium::MakeUnique<CFX_XMLElement>(L"ROOT");
-
- CFX_XMLTestParser parser(root.get(), stream);
+ CFX_XMLTestParser parser(stream);
ASSERT_EQ(FX_XmlSyntaxResult::ElementOpen, parser.DoSyntaxParse());
ASSERT_EQ(FX_XmlSyntaxResult::TagName, parser.DoSyntaxParse());
ASSERT_EQ(L"script", parser.GetTextData());
@@ -222,9 +213,7 @@ TEST(CFX_XMLParserTest, UnClosedCData) {
"</script>";
auto stream = MakeProxy(input);
- auto root = pdfium::MakeUnique<CFX_XMLElement>(L"ROOT");
-
- CFX_XMLTestParser parser(root.get(), stream);
+ CFX_XMLTestParser parser(stream);
ASSERT_EQ(FX_XmlSyntaxResult::ElementOpen, parser.DoSyntaxParse());
ASSERT_EQ(FX_XmlSyntaxResult::TagName, parser.DoSyntaxParse());
ASSERT_EQ(L"script", parser.GetTextData());
@@ -250,9 +239,7 @@ TEST(CFX_XMLParserTest, EmptyCData) {
"</script>";
auto stream = MakeProxy(input);
- auto root = pdfium::MakeUnique<CFX_XMLElement>(L"ROOT");
-
- CFX_XMLTestParser parser(root.get(), stream);
+ CFX_XMLTestParser parser(stream);
ASSERT_EQ(FX_XmlSyntaxResult::ElementOpen, parser.DoSyntaxParse());
ASSERT_EQ(FX_XmlSyntaxResult::TagName, parser.DoSyntaxParse());
ASSERT_EQ(L"script", parser.GetTextData());
@@ -285,9 +272,7 @@ TEST(CFX_XMLParserTest, Comment) {
"</script>";
auto stream = MakeProxy(input);
- auto root = pdfium::MakeUnique<CFX_XMLElement>(L"ROOT");
-
- CFX_XMLTestParser parser(root.get(), stream);
+ CFX_XMLTestParser parser(stream);
ASSERT_EQ(FX_XmlSyntaxResult::ElementOpen, parser.DoSyntaxParse());
ASSERT_EQ(FX_XmlSyntaxResult::TagName, parser.DoSyntaxParse());
ASSERT_EQ(L"script", parser.GetTextData());
@@ -317,9 +302,7 @@ TEST(CFX_XMLParserTest, IncorrectCommentStart) {
"</script>";
auto stream = MakeProxy(input);
- auto root = pdfium::MakeUnique<CFX_XMLElement>(L"ROOT");
-
- CFX_XMLTestParser parser(root.get(), stream);
+ CFX_XMLTestParser parser(stream);
ASSERT_EQ(FX_XmlSyntaxResult::ElementOpen, parser.DoSyntaxParse());
ASSERT_EQ(FX_XmlSyntaxResult::TagName, parser.DoSyntaxParse());
ASSERT_EQ(L"script", parser.GetTextData());
@@ -349,9 +332,7 @@ TEST(CFX_XMLParserTest, CommentEmpty) {
"</script>";
auto stream = MakeProxy(input);
- auto root = pdfium::MakeUnique<CFX_XMLElement>(L"ROOT");
-
- CFX_XMLTestParser parser(root.get(), stream);
+ CFX_XMLTestParser parser(stream);
ASSERT_EQ(FX_XmlSyntaxResult::ElementOpen, parser.DoSyntaxParse());
ASSERT_EQ(FX_XmlSyntaxResult::TagName, parser.DoSyntaxParse());
ASSERT_EQ(L"script", parser.GetTextData());
@@ -381,9 +362,7 @@ TEST(CFX_XMLParserTest, CommentThreeDash) {
"</script>";
auto stream = MakeProxy(input);
- auto root = pdfium::MakeUnique<CFX_XMLElement>(L"ROOT");
-
- CFX_XMLTestParser parser(root.get(), stream);
+ CFX_XMLTestParser parser(stream);
ASSERT_EQ(FX_XmlSyntaxResult::ElementOpen, parser.DoSyntaxParse());
ASSERT_EQ(FX_XmlSyntaxResult::TagName, parser.DoSyntaxParse());
ASSERT_EQ(L"script", parser.GetTextData());
@@ -407,9 +386,7 @@ TEST(CFX_XMLParserTest, CommentTwoDash) {
"</script>";
auto stream = MakeProxy(input);
- auto root = pdfium::MakeUnique<CFX_XMLElement>(L"ROOT");
-
- CFX_XMLTestParser parser(root.get(), stream);
+ CFX_XMLTestParser parser(stream);
ASSERT_EQ(FX_XmlSyntaxResult::ElementOpen, parser.DoSyntaxParse());
ASSERT_EQ(FX_XmlSyntaxResult::TagName, parser.DoSyntaxParse());
ASSERT_EQ(L"script", parser.GetTextData());
@@ -444,9 +421,7 @@ TEST(CFX_XMLParserTest, Entities) {
"</script>";
auto stream = MakeProxy(input);
- auto root = pdfium::MakeUnique<CFX_XMLElement>(L"ROOT");
-
- CFX_XMLTestParser parser(root.get(), stream);
+ CFX_XMLTestParser parser(stream);
ASSERT_EQ(FX_XmlSyntaxResult::ElementOpen, parser.DoSyntaxParse());
ASSERT_EQ(FX_XmlSyntaxResult::TagName, parser.DoSyntaxParse());
ASSERT_EQ(L"script", parser.GetTextData());
@@ -474,9 +449,7 @@ TEST(CFX_XMLParserTest, EntityOverflowHex) {
"</script>";
auto stream = MakeProxy(input);
- auto root = pdfium::MakeUnique<CFX_XMLElement>(L"ROOT");
-
- CFX_XMLTestParser parser(root.get(), stream);
+ CFX_XMLTestParser parser(stream);
ASSERT_EQ(FX_XmlSyntaxResult::ElementOpen, parser.DoSyntaxParse());
ASSERT_EQ(FX_XmlSyntaxResult::TagName, parser.DoSyntaxParse());
ASSERT_EQ(L"script", parser.GetTextData());
@@ -504,9 +477,7 @@ TEST(CFX_XMLParserTest, EntityOverflowDecimal) {
"</script>";
auto stream = MakeProxy(input);
- auto root = pdfium::MakeUnique<CFX_XMLElement>(L"ROOT");
-
- CFX_XMLTestParser parser(root.get(), stream);
+ CFX_XMLTestParser parser(stream);
ASSERT_EQ(FX_XmlSyntaxResult::ElementOpen, parser.DoSyntaxParse());
ASSERT_EQ(FX_XmlSyntaxResult::TagName, parser.DoSyntaxParse());
ASSERT_EQ(L"script", parser.GetTextData());
@@ -547,9 +518,7 @@ TEST(CFX_XMLParserTest, BadElementClose) {
const char* input = "</endtag>";
auto stream = MakeProxy(input);
- auto root = pdfium::MakeUnique<CFX_XMLElement>(L"ROOT");
-
- CFX_XMLTestParser parser(root.get(), stream);
+ CFX_XMLTestParser parser(stream);
ASSERT_EQ(FX_XmlSyntaxResult::Error, parser.DoSyntaxParse());
}
@@ -557,9 +526,7 @@ TEST(CFX_XMLParserTest, DoubleElementClose) {
const char* input = "<p></p></p>";
auto stream = MakeProxy(input);
- auto root = pdfium::MakeUnique<CFX_XMLElement>(L"ROOT");
-
- CFX_XMLTestParser parser(root.get(), stream);
+ CFX_XMLTestParser parser(stream);
ASSERT_EQ(FX_XmlSyntaxResult::ElementOpen, parser.DoSyntaxParse());
ASSERT_EQ(FX_XmlSyntaxResult::TagName, parser.DoSyntaxParse());
ASSERT_EQ(L"p", parser.GetTextData());
@@ -570,6 +537,26 @@ TEST(CFX_XMLParserTest, DoubleElementClose) {
ASSERT_EQ(FX_XmlSyntaxResult::Error, parser.DoSyntaxParse());
}
+TEST(CFX_XMLParserTest, ParseInstruction) {
+ const char* input =
+ "<?originalXFAVersion http://www.xfa.org/schema/xfa-template/3.3/ ?>"
+ "<form></form>";
+
+ auto stream = MakeProxy(input);
+ CFX_XMLTestParser parser(stream);
+
+ auto doc = parser.Parse();
+ ASSERT_TRUE(doc.get() != nullptr);
+
+ CFX_XMLElement* root = doc->GetRoot();
+ ASSERT_TRUE(root->GetFirstChild() != nullptr);
+ ASSERT_EQ(FX_XMLNODE_Instruction, root->GetFirstChild()->GetType());
+
+ CFX_XMLInstruction* instruction =
+ static_cast<CFX_XMLInstruction*>(root->GetFirstChild());
+ EXPECT_TRUE(instruction->IsOriginalXFAVersion());
+}
+
TEST(CFX_XMLParserTest, BadEntity) {
const char* input =
"<script>"
@@ -577,9 +564,7 @@ TEST(CFX_XMLParserTest, BadEntity) {
"</script>";
auto stream = MakeProxy(input);
- auto root = pdfium::MakeUnique<CFX_XMLElement>(L"ROOT");
-
- CFX_XMLTestParser parser(root.get(), stream);
+ CFX_XMLTestParser parser(stream);
ASSERT_EQ(FX_XmlSyntaxResult::ElementOpen, parser.DoSyntaxParse());
ASSERT_EQ(FX_XmlSyntaxResult::TagName, parser.DoSyntaxParse());
ASSERT_EQ(L"script", parser.GetTextData());
diff --git a/core/fxcrt/xml/cfx_xmltext.cpp b/core/fxcrt/xml/cfx_xmltext.cpp
index 2c324be1c9..73f0477482 100644
--- a/core/fxcrt/xml/cfx_xmltext.cpp
+++ b/core/fxcrt/xml/cfx_xmltext.cpp
@@ -6,6 +6,7 @@
#include "core/fxcrt/xml/cfx_xmltext.h"
+#include "core/fxcrt/xml/cfx_xmldocument.h"
#include "third_party/base/ptr_util.h"
CFX_XMLText::CFX_XMLText(const WideString& wsText)
@@ -17,8 +18,8 @@ FX_XMLNODETYPE CFX_XMLText::GetType() const {
return FX_XMLNODE_Text;
}
-std::unique_ptr<CFX_XMLNode> CFX_XMLText::Clone() {
- return pdfium::MakeUnique<CFX_XMLText>(m_wsText);
+CFX_XMLNode* CFX_XMLText::Clone(CFX_XMLDocument* doc) {
+ return doc->CreateNode<CFX_XMLText>(m_wsText);
}
void CFX_XMLText::Save(const RetainPtr<IFX_SeekableWriteStream>& pXMLStream) {
diff --git a/core/fxcrt/xml/cfx_xmltext.h b/core/fxcrt/xml/cfx_xmltext.h
index cc9c71d01c..c5c168059d 100644
--- a/core/fxcrt/xml/cfx_xmltext.h
+++ b/core/fxcrt/xml/cfx_xmltext.h
@@ -12,6 +12,8 @@
#include "core/fxcrt/fx_string.h"
#include "core/fxcrt/xml/cfx_xmlnode.h"
+class CFX_XMLDocument;
+
class CFX_XMLText : public CFX_XMLNode {
public:
explicit CFX_XMLText(const WideString& wsText);
@@ -19,7 +21,7 @@ class CFX_XMLText : public CFX_XMLNode {
// CFX_XMLNode
FX_XMLNODETYPE GetType() const override;
- std::unique_ptr<CFX_XMLNode> Clone() override;
+ CFX_XMLNode* Clone(CFX_XMLDocument* doc) override;
void Save(const RetainPtr<IFX_SeekableWriteStream>& pXMLStream) override;
WideString GetText() const { return m_wsText; }
diff --git a/core/fxcrt/xml/cfx_xmltext_unittest.cpp b/core/fxcrt/xml/cfx_xmltext_unittest.cpp
index ab977e9546..6e53f66612 100644
--- a/core/fxcrt/xml/cfx_xmltext_unittest.cpp
+++ b/core/fxcrt/xml/cfx_xmltext_unittest.cpp
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "core/fxcrt/xml/cfx_xmltext.h"
+#include "core/fxcrt/xml/cfx_xmldocument.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/string_write_stream.h"
#include "testing/test_support.h"
@@ -18,11 +19,13 @@ TEST(CFX_XMLTextTest, GetText) {
}
TEST(CFX_XMLTextTest, Clone) {
+ CFX_XMLDocument doc;
+
CFX_XMLText data(L"My Data");
- auto clone = data.Clone();
+ CFX_XMLNode* clone = data.Clone(&doc);
EXPECT_TRUE(clone != nullptr);
ASSERT_EQ(FX_XMLNODE_Text, clone->GetType());
- EXPECT_EQ(L"My Data", static_cast<CFX_XMLText*>(clone.get())->GetText());
+ EXPECT_EQ(L"My Data", static_cast<CFX_XMLText*>(clone)->GetText());
}
TEST(CFX_XMLTextTest, Save) {