1 // Copyright 2017 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "xfa/fxfa/parser/cxfa_node.h"
6 
7 #include "fxjs/xfa/cjx_node.h"
8 #include "testing/gtest/include/gtest/gtest.h"
9 #include "third_party/base/ptr_util.h"
10 #include "xfa/fxfa/parser/cxfa_document.h"
11 
12 namespace {
13 
14 class TestNode final : public CXFA_Node {
15  public:
TestNode(CXFA_Document * doc)16   explicit TestNode(CXFA_Document* doc)
17       : CXFA_Node(doc,
18                   XFA_PacketType::Form,
19                   (XFA_XDPPACKET_Template | XFA_XDPPACKET_Form),
20                   XFA_ObjectType::Node,
21                   XFA_Element::Node,
22                   {},
23                   {},
24                   pdfium::MakeUnique<CJX_Node>(this)) {}
25 
26   ~TestNode() override = default;
27 };
28 
29 }  // namespace
30 
31 class CXFANodeTest : public testing::Test {
32  public:
SetUp()33   void SetUp() override {
34     doc_ = pdfium::MakeUnique<CXFA_Document>(nullptr, nullptr);
35     node_ = pdfium::MakeUnique<TestNode>(doc_.get());
36   }
37 
TearDown()38   void TearDown() override {
39     node_ = nullptr;
40     doc_ = nullptr;
41   }
42 
GetDoc() const43   CXFA_Document* GetDoc() const { return doc_.get(); }
GetNode() const44   CXFA_Node* GetNode() const { return node_.get(); }
45 
46  private:
47   std::unique_ptr<CXFA_Document> doc_;
48   std::unique_ptr<TestNode> node_;
49 };
50 
TEST_F(CXFANodeTest,InsertFirstChild)51 TEST_F(CXFANodeTest, InsertFirstChild) {
52   EXPECT_EQ(nullptr, GetNode()->GetFirstChild());
53   EXPECT_EQ(nullptr, GetNode()->GetLastChild());
54 
55   CXFA_Node* child =
56       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
57   GetNode()->InsertChildAndNotify(-1, child);
58 
59   EXPECT_EQ(GetNode(), child->GetParent());
60   EXPECT_EQ(child, GetNode()->GetFirstChild());
61   EXPECT_EQ(child, GetNode()->GetLastChild());
62   EXPECT_EQ(nullptr, child->GetPrevSibling());
63   EXPECT_EQ(nullptr, child->GetNextSibling());
64 }
65 
TEST_F(CXFANodeTest,InsertChildByNegativeIndex)66 TEST_F(CXFANodeTest, InsertChildByNegativeIndex) {
67   CXFA_Node* child0 =
68       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
69   GetNode()->InsertChildAndNotify(-1, child0);
70 
71   CXFA_Node* child =
72       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
73   GetNode()->InsertChildAndNotify(-1, child);
74 
75   EXPECT_EQ(GetNode(), child->GetParent());
76   EXPECT_EQ(nullptr, child->GetNextSibling());
77   EXPECT_EQ(child0, child->GetPrevSibling());
78   EXPECT_EQ(child, child0->GetNextSibling());
79   EXPECT_EQ(nullptr, child0->GetPrevSibling());
80 
81   EXPECT_EQ(child0, GetNode()->GetFirstChild());
82   EXPECT_EQ(child, GetNode()->GetLastChild());
83 }
84 
TEST_F(CXFANodeTest,InsertChildByIndex)85 TEST_F(CXFANodeTest, InsertChildByIndex) {
86   CXFA_Node* child0 =
87       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
88   GetNode()->InsertChildAndNotify(-1, child0);
89 
90   CXFA_Node* child1 =
91       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
92   GetNode()->InsertChildAndNotify(-1, child1);
93 
94   CXFA_Node* child2 =
95       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
96   GetNode()->InsertChildAndNotify(-1, child2);
97 
98   CXFA_Node* child3 =
99       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
100   GetNode()->InsertChildAndNotify(-1, child3);
101 
102   CXFA_Node* child =
103       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
104   GetNode()->InsertChildAndNotify(2, child);
105 
106   EXPECT_EQ(GetNode(), child->GetParent());
107 
108   EXPECT_EQ(child0, GetNode()->GetFirstChild());
109   EXPECT_EQ(child1, child0->GetNextSibling());
110   EXPECT_EQ(child, child1->GetNextSibling());
111   EXPECT_EQ(child2, child->GetNextSibling());
112   EXPECT_EQ(child3, child2->GetNextSibling());
113   EXPECT_EQ(nullptr, child3->GetNextSibling());
114 
115   EXPECT_EQ(child3, GetNode()->GetLastChild());
116   EXPECT_EQ(child2, child3->GetPrevSibling());
117   EXPECT_EQ(child, child2->GetPrevSibling());
118   EXPECT_EQ(child1, child->GetPrevSibling());
119   EXPECT_EQ(child0, child1->GetPrevSibling());
120   EXPECT_EQ(nullptr, child0->GetPrevSibling());
121 }
122 
TEST_F(CXFANodeTest,InsertChildIndexPastEnd)123 TEST_F(CXFANodeTest, InsertChildIndexPastEnd) {
124   CXFA_Node* child0 =
125       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
126   GetNode()->InsertChildAndNotify(-1, child0);
127 
128   CXFA_Node* child1 =
129       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
130   GetNode()->InsertChildAndNotify(-1, child1);
131 
132   CXFA_Node* child =
133       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
134   GetNode()->InsertChildAndNotify(20, child);
135 
136   EXPECT_EQ(GetNode(), child->GetParent());
137   EXPECT_EQ(nullptr, child->GetNextSibling());
138   EXPECT_EQ(child1, child->GetPrevSibling());
139   EXPECT_EQ(child, child1->GetNextSibling());
140 
141   EXPECT_EQ(child0, GetNode()->GetFirstChild());
142   EXPECT_EQ(child, GetNode()->GetLastChild());
143 }
144 
TEST_F(CXFANodeTest,InsertFirstChildBeforeNullptr)145 TEST_F(CXFANodeTest, InsertFirstChildBeforeNullptr) {
146   EXPECT_EQ(nullptr, GetNode()->GetFirstChild());
147   EXPECT_EQ(nullptr, GetNode()->GetLastChild());
148 
149   CXFA_Node* child =
150       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
151   GetNode()->InsertChildAndNotify(child, nullptr);
152   EXPECT_EQ(child, GetNode()->GetFirstChild());
153   EXPECT_EQ(child, GetNode()->GetLastChild());
154 }
155 
TEST_F(CXFANodeTest,InsertBeforeWithNullBefore)156 TEST_F(CXFANodeTest, InsertBeforeWithNullBefore) {
157   CXFA_Node* child0 =
158       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
159   GetNode()->InsertChildAndNotify(-1, child0);
160 
161   CXFA_Node* child1 =
162       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
163   GetNode()->InsertChildAndNotify(-1, child1);
164 
165   CXFA_Node* child =
166       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
167   GetNode()->InsertChildAndNotify(child, nullptr);
168 
169   EXPECT_EQ(GetNode(), child->GetParent());
170   EXPECT_EQ(nullptr, child->GetNextSibling());
171   EXPECT_EQ(child1, child->GetPrevSibling());
172   EXPECT_EQ(child, child1->GetNextSibling());
173 
174   EXPECT_EQ(child0, GetNode()->GetFirstChild());
175   EXPECT_EQ(child, GetNode()->GetLastChild());
176 }
177 
TEST_F(CXFANodeTest,InsertBeforeFirstChild)178 TEST_F(CXFANodeTest, InsertBeforeFirstChild) {
179   CXFA_Node* child0 =
180       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
181   GetNode()->InsertChildAndNotify(-1, child0);
182 
183   CXFA_Node* child1 =
184       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
185   GetNode()->InsertChildAndNotify(-1, child1);
186 
187   CXFA_Node* child =
188       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
189   GetNode()->InsertChildAndNotify(child, child0);
190 
191   EXPECT_EQ(GetNode(), child->GetParent());
192   EXPECT_EQ(child0, child->GetNextSibling());
193   EXPECT_EQ(nullptr, child->GetPrevSibling());
194   EXPECT_EQ(child, child0->GetPrevSibling());
195 
196   EXPECT_EQ(child, GetNode()->GetFirstChild());
197   EXPECT_EQ(child1, GetNode()->GetLastChild());
198 }
199 
TEST_F(CXFANodeTest,InsertBefore)200 TEST_F(CXFANodeTest, InsertBefore) {
201   CXFA_Node* child0 =
202       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
203   GetNode()->InsertChildAndNotify(-1, child0);
204 
205   CXFA_Node* child1 =
206       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
207   GetNode()->InsertChildAndNotify(-1, child1);
208 
209   CXFA_Node* child2 =
210       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
211   GetNode()->InsertChildAndNotify(-1, child2);
212 
213   CXFA_Node* child3 =
214       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
215   GetNode()->InsertChildAndNotify(-1, child3);
216 
217   CXFA_Node* child =
218       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
219   GetNode()->InsertChildAndNotify(child, child2);
220 
221   EXPECT_EQ(GetNode(), child->GetParent());
222   EXPECT_EQ(child2, child->GetNextSibling());
223   EXPECT_EQ(child1, child->GetPrevSibling());
224   EXPECT_EQ(child, child1->GetNextSibling());
225   EXPECT_EQ(child, child2->GetPrevSibling());
226 
227   EXPECT_EQ(child0, GetNode()->GetFirstChild());
228   EXPECT_EQ(child3, GetNode()->GetLastChild());
229 }
230 
TEST_F(CXFANodeTest,RemoveOnlyChild)231 TEST_F(CXFANodeTest, RemoveOnlyChild) {
232   CXFA_Node* child0 =
233       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
234   GetNode()->InsertChildAndNotify(-1, child0);
235   EXPECT_EQ(child0, GetNode()->GetFirstChild());
236   EXPECT_EQ(child0, GetNode()->GetLastChild());
237 
238   GetNode()->RemoveChildAndNotify(child0, false);
239   EXPECT_EQ(nullptr, GetNode()->GetFirstChild());
240   EXPECT_EQ(nullptr, GetNode()->GetLastChild());
241   EXPECT_EQ(nullptr, child0->GetParent());
242   EXPECT_EQ(nullptr, child0->GetNextSibling());
243   EXPECT_EQ(nullptr, child0->GetPrevSibling());
244 }
245 
TEST_F(CXFANodeTest,RemoveFirstChild)246 TEST_F(CXFANodeTest, RemoveFirstChild) {
247   CXFA_Node* child0 =
248       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
249   GetNode()->InsertChildAndNotify(-1, child0);
250 
251   CXFA_Node* child1 =
252       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
253   GetNode()->InsertChildAndNotify(-1, child1);
254 
255   CXFA_Node* child2 =
256       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
257   GetNode()->InsertChildAndNotify(-1, child2);
258   EXPECT_EQ(child0, GetNode()->GetFirstChild());
259   EXPECT_EQ(child2, GetNode()->GetLastChild());
260 
261   GetNode()->RemoveChildAndNotify(child0, false);
262   EXPECT_EQ(child1, GetNode()->GetFirstChild());
263   EXPECT_EQ(child2, GetNode()->GetLastChild());
264   EXPECT_EQ(nullptr, child1->GetPrevSibling());
265   EXPECT_EQ(nullptr, child0->GetParent());
266   EXPECT_EQ(nullptr, child0->GetNextSibling());
267   EXPECT_EQ(nullptr, child0->GetPrevSibling());
268 }
269 
TEST_F(CXFANodeTest,RemoveLastChild)270 TEST_F(CXFANodeTest, RemoveLastChild) {
271   CXFA_Node* child0 =
272       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
273   GetNode()->InsertChildAndNotify(-1, child0);
274 
275   CXFA_Node* child1 =
276       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
277   GetNode()->InsertChildAndNotify(-1, child1);
278 
279   CXFA_Node* child2 =
280       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
281   GetNode()->InsertChildAndNotify(-1, child2);
282   EXPECT_EQ(child0, GetNode()->GetFirstChild());
283   EXPECT_EQ(child2, GetNode()->GetLastChild());
284 
285   GetNode()->RemoveChildAndNotify(child2, false);
286   EXPECT_EQ(child0, GetNode()->GetFirstChild());
287   EXPECT_EQ(child1, GetNode()->GetLastChild());
288   EXPECT_EQ(nullptr, child1->GetNextSibling());
289   EXPECT_EQ(nullptr, child2->GetParent());
290   EXPECT_EQ(nullptr, child2->GetNextSibling());
291   EXPECT_EQ(nullptr, child2->GetPrevSibling());
292 }
293 
TEST_F(CXFANodeTest,RemoveChild)294 TEST_F(CXFANodeTest, RemoveChild) {
295   CXFA_Node* child0 =
296       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
297   GetNode()->InsertChildAndNotify(-1, child0);
298 
299   CXFA_Node* child1 =
300       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
301   GetNode()->InsertChildAndNotify(-1, child1);
302 
303   CXFA_Node* child2 =
304       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
305   GetNode()->InsertChildAndNotify(-1, child2);
306   EXPECT_EQ(child0, GetNode()->GetFirstChild());
307   EXPECT_EQ(child2, GetNode()->GetLastChild());
308 
309   GetNode()->RemoveChildAndNotify(child1, false);
310   EXPECT_EQ(child0, GetNode()->GetFirstChild());
311   EXPECT_EQ(child2, GetNode()->GetLastChild());
312   EXPECT_EQ(child2, child0->GetNextSibling());
313   EXPECT_EQ(child0, child2->GetPrevSibling());
314   EXPECT_EQ(nullptr, child1->GetParent());
315   EXPECT_EQ(nullptr, child1->GetNextSibling());
316   EXPECT_EQ(nullptr, child1->GetPrevSibling());
317 }
318 
TEST_F(CXFANodeTest,InsertChildWithParent)319 TEST_F(CXFANodeTest, InsertChildWithParent) {
320   CXFA_Node* child0 =
321       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
322   CXFA_Node* child1 =
323       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
324   child0->InsertChildAndNotify(-1, child1);
325 
326   EXPECT_DEATH_IF_SUPPORTED(GetNode()->InsertChildAndNotify(0, child1), "");
327 }
328 
TEST_F(CXFANodeTest,InsertNullChild)329 TEST_F(CXFANodeTest, InsertNullChild) {
330   EXPECT_DEATH_IF_SUPPORTED(GetNode()->InsertChildAndNotify(0, nullptr), "");
331 }
332 
TEST_F(CXFANodeTest,InsertBeforeWithNullChild)333 TEST_F(CXFANodeTest, InsertBeforeWithNullChild) {
334   EXPECT_DEATH_IF_SUPPORTED(GetNode()->InsertChildAndNotify(nullptr, nullptr),
335                             "");
336 }
337 
TEST_F(CXFANodeTest,InsertBeforeWithBeforeInAnotherParent)338 TEST_F(CXFANodeTest, InsertBeforeWithBeforeInAnotherParent) {
339   CXFA_Node* child0 =
340       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
341   GetNode()->InsertChildAndNotify(-1, child0);
342 
343   CXFA_Node* child1 =
344       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
345   child0->InsertChildAndNotify(-1, child1);
346 
347   CXFA_Node* child =
348       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
349   EXPECT_DEATH_IF_SUPPORTED(GetNode()->InsertChildAndNotify(child, child1), "");
350 }
351 
TEST_F(CXFANodeTest,InsertBeforeWithNodeInAnotherParent)352 TEST_F(CXFANodeTest, InsertBeforeWithNodeInAnotherParent) {
353   CXFA_Node* child0 =
354       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
355   GetNode()->InsertChildAndNotify(-1, child0);
356 
357   CXFA_Node* child1 =
358       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
359   child0->InsertChildAndNotify(-1, child1);
360 
361   EXPECT_DEATH_IF_SUPPORTED(GetNode()->InsertChildAndNotify(child1, nullptr),
362                             "");
363 }
364 
TEST_F(CXFANodeTest,RemoveChildNullptr)365 TEST_F(CXFANodeTest, RemoveChildNullptr) {
366   EXPECT_DEATH_IF_SUPPORTED(GetNode()->RemoveChildAndNotify(nullptr, false),
367                             "");
368 }
369 
TEST_F(CXFANodeTest,RemoveChildAnotherParent)370 TEST_F(CXFANodeTest, RemoveChildAnotherParent) {
371   CXFA_Node* child0 =
372       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
373   GetNode()->InsertChildAndNotify(-1, child0);
374 
375   CXFA_Node* child1 =
376       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
377   child0->InsertChildAndNotify(-1, child1);
378 
379   GetNode()->RemoveChildAndNotify(child1, false);
380   EXPECT_EQ(child0, child1->GetParent());
381 }
382