xref: /aosp_15_r20/external/pdfium/core/fpdfapi/parser/object_tree_traversal_util_embeddertest.cpp (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
1 // Copyright 2023 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 "core/fpdfapi/parser/object_tree_traversal_util.h"
6 
7 #include <stdint.h>
8 
9 #include <set>
10 
11 #include "core/fpdfapi/parser/cpdf_document.h"
12 #include "testing/embedder_test.h"
13 #include "testing/gmock/include/gmock/gmock.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15 
16 using testing::UnorderedElementsAreArray;
17 using ObjectTreeTraversalUtilEmbedderTest = EmbedderTest;
18 
19 namespace {
20 
GetCPDFDocument(FPDF_DOCUMENT document)21 CPDF_Document* GetCPDFDocument(FPDF_DOCUMENT document) {
22   // This is cheating slightly to avoid a layering violation, since this file
23   // cannot include fpdfsdk/cpdfsdk_helpers.h to get access to
24   // CPDFDocumentFromFPDFDocument().
25   return reinterpret_cast<CPDF_Document*>((document));
26 }
27 
28 }  // namespace
29 
TEST_F(ObjectTreeTraversalUtilEmbedderTest,GetObjectsWithReferencesBasic)30 TEST_F(ObjectTreeTraversalUtilEmbedderTest, GetObjectsWithReferencesBasic) {
31   ASSERT_TRUE(OpenDocument("hello_world.pdf"));
32   CPDF_Document* doc = GetCPDFDocument(document());
33   std::set<uint32_t> referenced_objects = GetObjectsWithReferences(doc);
34   EXPECT_THAT(referenced_objects,
35               UnorderedElementsAreArray({1, 2, 3, 4, 5, 6}));
36 }
37 
TEST_F(ObjectTreeTraversalUtilEmbedderTest,GetObjectsWithReferencesNewDoc)38 TEST_F(ObjectTreeTraversalUtilEmbedderTest, GetObjectsWithReferencesNewDoc) {
39   ScopedFPDFDocument new_doc(FPDF_CreateNewDocument());
40   CPDF_Document* doc = GetCPDFDocument(new_doc.get());
41   std::set<uint32_t> referenced_objects = GetObjectsWithReferences(doc);
42   // Empty documents have a catalog and an empty pages object.
43   EXPECT_THAT(referenced_objects, UnorderedElementsAreArray({1, 2}));
44 }
45 
TEST_F(ObjectTreeTraversalUtilEmbedderTest,GetObjectsWithReferencesCircularRefs)46 TEST_F(ObjectTreeTraversalUtilEmbedderTest,
47        GetObjectsWithReferencesCircularRefs) {
48   ASSERT_TRUE(OpenDocument("circular_viewer_ref.pdf"));
49   CPDF_Document* doc = GetCPDFDocument(document());
50   std::set<uint32_t> referenced_objects = GetObjectsWithReferences(doc);
51   // The trailer points at a catalog, and the catalog only references itself.
52   EXPECT_THAT(referenced_objects, UnorderedElementsAreArray({1}));
53 }
54 
TEST_F(ObjectTreeTraversalUtilEmbedderTest,GetObjectsWithReferencesCrossRefStream)55 TEST_F(ObjectTreeTraversalUtilEmbedderTest,
56        GetObjectsWithReferencesCrossRefStream) {
57   ASSERT_TRUE(OpenDocument("bug_1399.pdf"));
58   CPDF_Document* doc = GetCPDFDocument(document());
59   std::set<uint32_t> referenced_objects = GetObjectsWithReferences(doc);
60   // The trailer is the dictionary inside /XRef object 16 0. Note that it
61   // references object 3 0, but the rest of the document does not.
62   EXPECT_THAT(referenced_objects,
63               UnorderedElementsAreArray({1, 2, 3, 4, 5, 12, 13, 14, 16}));
64 }
65 
TEST_F(ObjectTreeTraversalUtilEmbedderTest,GetObjectsWithReferencesObjectZero)66 TEST_F(ObjectTreeTraversalUtilEmbedderTest,
67        GetObjectsWithReferencesObjectZero) {
68   ASSERT_TRUE(OpenDocument("rectangles_object_zero.pdf"));
69   CPDF_Document* doc = GetCPDFDocument(document());
70   std::set<uint32_t> referenced_objects = GetObjectsWithReferences(doc);
71   EXPECT_THAT(referenced_objects, UnorderedElementsAreArray({1, 2, 3, 4}));
72 }
73 
TEST_F(ObjectTreeTraversalUtilEmbedderTest,GetObjectsWithMultipleReferencesBasic)74 TEST_F(ObjectTreeTraversalUtilEmbedderTest,
75        GetObjectsWithMultipleReferencesBasic) {
76   ASSERT_TRUE(OpenDocument("hello_world.pdf"));
77   CPDF_Document* doc = GetCPDFDocument(document());
78   std::set<uint32_t> referenced_objects = GetObjectsWithMultipleReferences(doc);
79   EXPECT_TRUE(referenced_objects.empty());
80 }
81 
TEST_F(ObjectTreeTraversalUtilEmbedderTest,GetObjectsWithMultipleReferencesNewDoc)82 TEST_F(ObjectTreeTraversalUtilEmbedderTest,
83        GetObjectsWithMultipleReferencesNewDoc) {
84   ScopedFPDFDocument new_doc(FPDF_CreateNewDocument());
85   CPDF_Document* doc = GetCPDFDocument(new_doc.get());
86   std::set<uint32_t> referenced_objects = GetObjectsWithMultipleReferences(doc);
87   EXPECT_TRUE(referenced_objects.empty());
88 }
89 
TEST_F(ObjectTreeTraversalUtilEmbedderTest,GetObjectsWithMultipleReferencesCircularRefs)90 TEST_F(ObjectTreeTraversalUtilEmbedderTest,
91        GetObjectsWithMultipleReferencesCircularRefs) {
92   ASSERT_TRUE(OpenDocument("circular_viewer_ref.pdf"));
93   CPDF_Document* doc = GetCPDFDocument(document());
94   std::set<uint32_t> referenced_objects = GetObjectsWithMultipleReferences(doc);
95   EXPECT_TRUE(referenced_objects.empty());
96 }
97 
TEST_F(ObjectTreeTraversalUtilEmbedderTest,GetObjectsWithMultipleReferencesSharedObjects)98 TEST_F(ObjectTreeTraversalUtilEmbedderTest,
99        GetObjectsWithMultipleReferencesSharedObjects) {
100   ASSERT_TRUE(OpenDocument("hello_world_2_pages.pdf"));
101   CPDF_Document* doc = GetCPDFDocument(document());
102   std::set<uint32_t> referenced_objects = GetObjectsWithMultipleReferences(doc);
103   EXPECT_THAT(referenced_objects, UnorderedElementsAreArray({5, 6, 7}));
104 }
105 
TEST_F(ObjectTreeTraversalUtilEmbedderTest,GetObjectsWithMultipleReferencesObjectZero)106 TEST_F(ObjectTreeTraversalUtilEmbedderTest,
107        GetObjectsWithMultipleReferencesObjectZero) {
108   ASSERT_TRUE(OpenDocument("rectangles_object_zero.pdf"));
109   CPDF_Document* doc = GetCPDFDocument(document());
110   std::set<uint32_t> referenced_objects = GetObjectsWithMultipleReferences(doc);
111   EXPECT_TRUE(referenced_objects.empty());
112 }
113