xref: /aosp_15_r20/external/pdfium/xfa/fxfa/parser/cxfa_node_unittest.cpp (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
1 // Copyright 2017 The PDFium Authors
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/gc/heap.h"
8 #include "fxjs/xfa/cjx_node.h"
9 #include "testing/fxgc_unittest.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11 #include "v8/include/cppgc/allocation.h"
12 #include "v8/include/cppgc/persistent.h"
13 #include "xfa/fxfa/parser/cxfa_document.h"
14 
15 namespace {
16 
17 class TestNode final : public CXFA_Node {
18  public:
19   CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
20   ~TestNode() override = default;
21 
22  private:
TestNode(CXFA_Document * doc)23   explicit TestNode(CXFA_Document* doc)
24       : CXFA_Node(doc,
25                   XFA_PacketType::Form,
26                   {XFA_XDPPACKET::kTemplate, XFA_XDPPACKET::kForm},
27                   XFA_ObjectType::Node,
28                   XFA_Element::Node,
29                   {},
30                   {},
31                   cppgc::MakeGarbageCollected<CJX_Node>(
32                       doc->GetHeap()->GetAllocationHandle(),
33                       this)) {}
34 };
35 
36 }  // namespace
37 
38 class CXFANodeTest : public FXGCUnitTest {
39  public:
SetUp()40   void SetUp() override {
41     FXGCUnitTest::SetUp();
42     doc_ = cppgc::MakeGarbageCollected<CXFA_Document>(
43         heap()->GetAllocationHandle(), nullptr, heap(), nullptr);
44     node_ = cppgc::MakeGarbageCollected<TestNode>(heap()->GetAllocationHandle(),
45                                                   doc_);
46   }
47 
TearDown()48   void TearDown() override {
49     node_.Clear();
50     doc_.Clear();
51     FXGCUnitTest::TearDown();
52   }
53 
GetDoc() const54   CXFA_Document* GetDoc() const { return doc_; }
GetNode() const55   CXFA_Node* GetNode() const { return node_; }
56 
57  private:
58   cppgc::Persistent<CXFA_Document> doc_;
59   cppgc::Persistent<TestNode> node_;
60 };
61 
TEST_F(CXFANodeTest,InsertFirstChild)62 TEST_F(CXFANodeTest, InsertFirstChild) {
63   EXPECT_FALSE(GetNode()->GetFirstChild());
64   EXPECT_FALSE(GetNode()->GetLastChild());
65 
66   CXFA_Node* child =
67       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
68   GetNode()->InsertChildAndNotify(-1, child);
69 
70   EXPECT_EQ(GetNode(), child->GetParent());
71   EXPECT_EQ(child, GetNode()->GetFirstChild());
72   EXPECT_EQ(child, GetNode()->GetLastChild());
73   EXPECT_FALSE(child->GetPrevSibling());
74   EXPECT_FALSE(child->GetNextSibling());
75 }
76 
TEST_F(CXFANodeTest,InsertChildByNegativeIndex)77 TEST_F(CXFANodeTest, InsertChildByNegativeIndex) {
78   CXFA_Node* child0 =
79       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
80   GetNode()->InsertChildAndNotify(-1, child0);
81 
82   CXFA_Node* child =
83       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
84   GetNode()->InsertChildAndNotify(-1, child);
85 
86   EXPECT_EQ(GetNode(), child->GetParent());
87   EXPECT_FALSE(child->GetNextSibling());
88   EXPECT_EQ(child0, child->GetPrevSibling());
89   EXPECT_EQ(child, child0->GetNextSibling());
90   EXPECT_FALSE(child0->GetPrevSibling());
91 
92   EXPECT_EQ(child0, GetNode()->GetFirstChild());
93   EXPECT_EQ(child, GetNode()->GetLastChild());
94 }
95 
TEST_F(CXFANodeTest,InsertChildByIndex)96 TEST_F(CXFANodeTest, InsertChildByIndex) {
97   CXFA_Node* child0 =
98       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
99   GetNode()->InsertChildAndNotify(-1, child0);
100 
101   CXFA_Node* child1 =
102       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
103   GetNode()->InsertChildAndNotify(-1, child1);
104 
105   CXFA_Node* child2 =
106       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
107   GetNode()->InsertChildAndNotify(-1, child2);
108 
109   CXFA_Node* child3 =
110       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
111   GetNode()->InsertChildAndNotify(-1, child3);
112 
113   CXFA_Node* child =
114       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
115   GetNode()->InsertChildAndNotify(2, child);
116 
117   EXPECT_EQ(GetNode(), child->GetParent());
118 
119   EXPECT_EQ(child0, GetNode()->GetFirstChild());
120   EXPECT_EQ(child1, child0->GetNextSibling());
121   EXPECT_EQ(child, child1->GetNextSibling());
122   EXPECT_EQ(child2, child->GetNextSibling());
123   EXPECT_EQ(child3, child2->GetNextSibling());
124   EXPECT_FALSE(child3->GetNextSibling());
125 
126   EXPECT_EQ(child3, GetNode()->GetLastChild());
127   EXPECT_EQ(child2, child3->GetPrevSibling());
128   EXPECT_EQ(child, child2->GetPrevSibling());
129   EXPECT_EQ(child1, child->GetPrevSibling());
130   EXPECT_EQ(child0, child1->GetPrevSibling());
131   EXPECT_FALSE(child0->GetPrevSibling());
132 }
133 
TEST_F(CXFANodeTest,InsertChildIndexPastEnd)134 TEST_F(CXFANodeTest, InsertChildIndexPastEnd) {
135   CXFA_Node* child0 =
136       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
137   GetNode()->InsertChildAndNotify(-1, child0);
138 
139   CXFA_Node* child1 =
140       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
141   GetNode()->InsertChildAndNotify(-1, child1);
142 
143   CXFA_Node* child =
144       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
145   GetNode()->InsertChildAndNotify(20, child);
146 
147   EXPECT_EQ(GetNode(), child->GetParent());
148   EXPECT_FALSE(child->GetNextSibling());
149   EXPECT_EQ(child1, child->GetPrevSibling());
150   EXPECT_EQ(child, child1->GetNextSibling());
151 
152   EXPECT_EQ(child0, GetNode()->GetFirstChild());
153   EXPECT_EQ(child, GetNode()->GetLastChild());
154 }
155 
TEST_F(CXFANodeTest,InsertFirstChildBeforeNullptr)156 TEST_F(CXFANodeTest, InsertFirstChildBeforeNullptr) {
157   EXPECT_FALSE(GetNode()->GetFirstChild());
158   EXPECT_FALSE(GetNode()->GetLastChild());
159 
160   CXFA_Node* child =
161       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
162   GetNode()->InsertChildAndNotify(child, nullptr);
163   EXPECT_EQ(child, GetNode()->GetFirstChild());
164   EXPECT_EQ(child, GetNode()->GetLastChild());
165 }
166 
TEST_F(CXFANodeTest,InsertBeforeWithNullBefore)167 TEST_F(CXFANodeTest, InsertBeforeWithNullBefore) {
168   CXFA_Node* child0 =
169       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
170   GetNode()->InsertChildAndNotify(-1, child0);
171 
172   CXFA_Node* child1 =
173       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
174   GetNode()->InsertChildAndNotify(-1, child1);
175 
176   CXFA_Node* child =
177       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
178   GetNode()->InsertChildAndNotify(child, nullptr);
179 
180   EXPECT_EQ(GetNode(), child->GetParent());
181   EXPECT_FALSE(child->GetNextSibling());
182   EXPECT_EQ(child1, child->GetPrevSibling());
183   EXPECT_EQ(child, child1->GetNextSibling());
184 
185   EXPECT_EQ(child0, GetNode()->GetFirstChild());
186   EXPECT_EQ(child, GetNode()->GetLastChild());
187 }
188 
TEST_F(CXFANodeTest,InsertBeforeFirstChild)189 TEST_F(CXFANodeTest, InsertBeforeFirstChild) {
190   CXFA_Node* child0 =
191       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
192   GetNode()->InsertChildAndNotify(-1, child0);
193 
194   CXFA_Node* child1 =
195       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
196   GetNode()->InsertChildAndNotify(-1, child1);
197 
198   CXFA_Node* child =
199       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
200   GetNode()->InsertChildAndNotify(child, child0);
201 
202   EXPECT_EQ(GetNode(), child->GetParent());
203   EXPECT_EQ(child0, child->GetNextSibling());
204   EXPECT_FALSE(child->GetPrevSibling());
205   EXPECT_EQ(child, child0->GetPrevSibling());
206 
207   EXPECT_EQ(child, GetNode()->GetFirstChild());
208   EXPECT_EQ(child1, GetNode()->GetLastChild());
209 }
210 
TEST_F(CXFANodeTest,InsertBefore)211 TEST_F(CXFANodeTest, InsertBefore) {
212   CXFA_Node* child0 =
213       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
214   GetNode()->InsertChildAndNotify(-1, child0);
215 
216   CXFA_Node* child1 =
217       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
218   GetNode()->InsertChildAndNotify(-1, child1);
219 
220   CXFA_Node* child2 =
221       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
222   GetNode()->InsertChildAndNotify(-1, child2);
223 
224   CXFA_Node* child3 =
225       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
226   GetNode()->InsertChildAndNotify(-1, child3);
227 
228   CXFA_Node* child =
229       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
230   GetNode()->InsertChildAndNotify(child, child2);
231 
232   EXPECT_EQ(GetNode(), child->GetParent());
233   EXPECT_EQ(child2, child->GetNextSibling());
234   EXPECT_EQ(child1, child->GetPrevSibling());
235   EXPECT_EQ(child, child1->GetNextSibling());
236   EXPECT_EQ(child, child2->GetPrevSibling());
237 
238   EXPECT_EQ(child0, GetNode()->GetFirstChild());
239   EXPECT_EQ(child3, GetNode()->GetLastChild());
240 }
241 
TEST_F(CXFANodeTest,RemoveOnlyChild)242 TEST_F(CXFANodeTest, RemoveOnlyChild) {
243   CXFA_Node* child0 =
244       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
245   GetNode()->InsertChildAndNotify(-1, child0);
246   EXPECT_EQ(child0, GetNode()->GetFirstChild());
247   EXPECT_EQ(child0, GetNode()->GetLastChild());
248 
249   GetNode()->RemoveChildAndNotify(child0, false);
250   EXPECT_FALSE(GetNode()->GetFirstChild());
251   EXPECT_FALSE(GetNode()->GetLastChild());
252   EXPECT_FALSE(child0->GetParent());
253   EXPECT_FALSE(child0->GetNextSibling());
254   EXPECT_FALSE(child0->GetPrevSibling());
255 }
256 
TEST_F(CXFANodeTest,RemoveFirstChild)257 TEST_F(CXFANodeTest, RemoveFirstChild) {
258   CXFA_Node* child0 =
259       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
260   GetNode()->InsertChildAndNotify(-1, child0);
261 
262   CXFA_Node* child1 =
263       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
264   GetNode()->InsertChildAndNotify(-1, child1);
265 
266   CXFA_Node* child2 =
267       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
268   GetNode()->InsertChildAndNotify(-1, child2);
269   EXPECT_EQ(child0, GetNode()->GetFirstChild());
270   EXPECT_EQ(child2, GetNode()->GetLastChild());
271 
272   GetNode()->RemoveChildAndNotify(child0, false);
273   EXPECT_EQ(child1, GetNode()->GetFirstChild());
274   EXPECT_EQ(child2, GetNode()->GetLastChild());
275   EXPECT_FALSE(child1->GetPrevSibling());
276   EXPECT_FALSE(child0->GetParent());
277   EXPECT_FALSE(child0->GetNextSibling());
278   EXPECT_FALSE(child0->GetPrevSibling());
279 }
280 
TEST_F(CXFANodeTest,RemoveLastChild)281 TEST_F(CXFANodeTest, RemoveLastChild) {
282   CXFA_Node* child0 =
283       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
284   GetNode()->InsertChildAndNotify(-1, child0);
285 
286   CXFA_Node* child1 =
287       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
288   GetNode()->InsertChildAndNotify(-1, child1);
289 
290   CXFA_Node* child2 =
291       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
292   GetNode()->InsertChildAndNotify(-1, child2);
293   EXPECT_EQ(child0, GetNode()->GetFirstChild());
294   EXPECT_EQ(child2, GetNode()->GetLastChild());
295 
296   GetNode()->RemoveChildAndNotify(child2, false);
297   EXPECT_EQ(child0, GetNode()->GetFirstChild());
298   EXPECT_EQ(child1, GetNode()->GetLastChild());
299   EXPECT_FALSE(child1->GetNextSibling());
300   EXPECT_FALSE(child2->GetParent());
301   EXPECT_FALSE(child2->GetNextSibling());
302   EXPECT_FALSE(child2->GetPrevSibling());
303 }
304 
TEST_F(CXFANodeTest,RemoveChild)305 TEST_F(CXFANodeTest, RemoveChild) {
306   CXFA_Node* child0 =
307       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
308   GetNode()->InsertChildAndNotify(-1, child0);
309 
310   CXFA_Node* child1 =
311       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
312   GetNode()->InsertChildAndNotify(-1, child1);
313 
314   CXFA_Node* child2 =
315       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
316   GetNode()->InsertChildAndNotify(-1, child2);
317   EXPECT_EQ(child0, GetNode()->GetFirstChild());
318   EXPECT_EQ(child2, GetNode()->GetLastChild());
319 
320   GetNode()->RemoveChildAndNotify(child1, false);
321   EXPECT_EQ(child0, GetNode()->GetFirstChild());
322   EXPECT_EQ(child2, GetNode()->GetLastChild());
323   EXPECT_EQ(child2, child0->GetNextSibling());
324   EXPECT_EQ(child0, child2->GetPrevSibling());
325   EXPECT_FALSE(child1->GetParent());
326   EXPECT_FALSE(child1->GetNextSibling());
327   EXPECT_FALSE(child1->GetPrevSibling());
328 }
329 
TEST_F(CXFANodeTest,InsertChildWithParent)330 TEST_F(CXFANodeTest, InsertChildWithParent) {
331   CXFA_Node* child0 =
332       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
333   CXFA_Node* child1 =
334       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
335   child0->InsertChildAndNotify(-1, child1);
336 
337   EXPECT_DEATH_IF_SUPPORTED(GetNode()->InsertChildAndNotify(0, child1), "");
338 }
339 
TEST_F(CXFANodeTest,InsertNullChild)340 TEST_F(CXFANodeTest, InsertNullChild) {
341   EXPECT_DEATH_IF_SUPPORTED(GetNode()->InsertChildAndNotify(0, nullptr), "");
342 }
343 
TEST_F(CXFANodeTest,InsertBeforeWithNullChild)344 TEST_F(CXFANodeTest, InsertBeforeWithNullChild) {
345   EXPECT_DEATH_IF_SUPPORTED(GetNode()->InsertChildAndNotify(nullptr, nullptr),
346                             "");
347 }
348 
TEST_F(CXFANodeTest,InsertBeforeWithBeforeInAnotherParent)349 TEST_F(CXFANodeTest, InsertBeforeWithBeforeInAnotherParent) {
350   CXFA_Node* child0 =
351       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
352   GetNode()->InsertChildAndNotify(-1, child0);
353 
354   CXFA_Node* child1 =
355       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
356   child0->InsertChildAndNotify(-1, child1);
357 
358   CXFA_Node* child =
359       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
360   EXPECT_DEATH_IF_SUPPORTED(GetNode()->InsertChildAndNotify(child, child1), "");
361 }
362 
TEST_F(CXFANodeTest,InsertBeforeWithNodeInAnotherParent)363 TEST_F(CXFANodeTest, InsertBeforeWithNodeInAnotherParent) {
364   CXFA_Node* child0 =
365       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
366   GetNode()->InsertChildAndNotify(-1, child0);
367 
368   CXFA_Node* child1 =
369       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
370   child0->InsertChildAndNotify(-1, child1);
371 
372   EXPECT_DEATH_IF_SUPPORTED(GetNode()->InsertChildAndNotify(child1, nullptr),
373                             "");
374 }
375 
TEST_F(CXFANodeTest,RemoveChildNullptr)376 TEST_F(CXFANodeTest, RemoveChildNullptr) {
377   EXPECT_DEATH_IF_SUPPORTED(GetNode()->RemoveChildAndNotify(nullptr, false),
378                             "");
379 }
380 
TEST_F(CXFANodeTest,RemoveChildAnotherParent)381 TEST_F(CXFANodeTest, RemoveChildAnotherParent) {
382   CXFA_Node* child0 =
383       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
384   GetNode()->InsertChildAndNotify(-1, child0);
385 
386   CXFA_Node* child1 =
387       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
388   child0->InsertChildAndNotify(-1, child1);
389 
390   GetNode()->RemoveChildAndNotify(child1, false);
391   EXPECT_EQ(child0, child1->GetParent());
392 }
393 
TEST_F(CXFANodeTest,AncestorOf)394 TEST_F(CXFANodeTest, AncestorOf) {
395   CXFA_Node* child0 =
396       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
397   GetNode()->InsertChildAndNotify(-1, child0);
398 
399   CXFA_Node* child1 =
400       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
401   GetNode()->InsertChildAndNotify(-1, child1);
402 
403   CXFA_Node* grandchild =
404       GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
405   child0->InsertChildAndNotify(-1, grandchild);
406 
407   EXPECT_TRUE(GetNode()->IsAncestorOf(child0));
408   EXPECT_TRUE(GetNode()->IsAncestorOf(child1));
409   EXPECT_FALSE(child1->IsAncestorOf(child0));
410   EXPECT_TRUE(child0->IsAncestorOf(grandchild));
411   EXPECT_TRUE(GetNode()->IsAncestorOf(grandchild));
412   EXPECT_FALSE(child1->IsAncestorOf(grandchild));
413 }
414 
TEST_F(CXFANodeTest,DeltaObjectIsNode)415 TEST_F(CXFANodeTest, DeltaObjectIsNode) {
416   CXFA_Node* delta =
417       CXFA_Node::Create(GetDoc(), XFA_Element::Delta, XFA_PacketType::Form);
418   ASSERT_TRUE(delta);
419   ASSERT_TRUE(delta->IsNode());
420 
421   // This call should not crash, like in crbug.com/1465239.
422   delta->JSObject()->SetAttributeByEnum(XFA_Attribute::Name, L"delta",
423                                         /*bNotify=*/false);
424 }
425