blob: c90c77e41b722abce3414f79dc791852fe8cb18e [file] [log] [blame]
kumarashishg826308d2023-06-23 13:21:22 +00001// 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
16using testing::UnorderedElementsAreArray;
17using ObjectTreeTraversalUtilEmbedderTest = EmbedderTest;
18
19namespace {
20
21CPDF_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
30TEST_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
38TEST_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
46TEST_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
55TEST_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
66TEST_F(ObjectTreeTraversalUtilEmbedderTest,
67 GetObjectsWithMultipleReferencesBasic) {
68 ASSERT_TRUE(OpenDocument("hello_world.pdf"));
69 CPDF_Document* doc = GetCPDFDocument(document());
70 std::set<uint32_t> referenced_objects = GetObjectsWithMultipleReferences(doc);
71 EXPECT_TRUE(referenced_objects.empty());
72}
73
74TEST_F(ObjectTreeTraversalUtilEmbedderTest,
75 GetObjectsWithMultipleReferencesNewDoc) {
76 ScopedFPDFDocument new_doc(FPDF_CreateNewDocument());
77 CPDF_Document* doc = GetCPDFDocument(new_doc.get());
78 std::set<uint32_t> referenced_objects = GetObjectsWithMultipleReferences(doc);
79 EXPECT_TRUE(referenced_objects.empty());
80}
81
82TEST_F(ObjectTreeTraversalUtilEmbedderTest,
83 GetObjectsWithMultipleReferencesCircularRefs) {
84 ASSERT_TRUE(OpenDocument("circular_viewer_ref.pdf"));
85 CPDF_Document* doc = GetCPDFDocument(document());
86 std::set<uint32_t> referenced_objects = GetObjectsWithMultipleReferences(doc);
87 EXPECT_TRUE(referenced_objects.empty());
88}
89
90TEST_F(ObjectTreeTraversalUtilEmbedderTest,
91 GetObjectsWithMultipleReferencesSharedObjects) {
92 ASSERT_TRUE(OpenDocument("hello_world_2_pages.pdf"));
93 CPDF_Document* doc = GetCPDFDocument(document());
94 std::set<uint32_t> referenced_objects = GetObjectsWithMultipleReferences(doc);
95 EXPECT_THAT(referenced_objects, UnorderedElementsAreArray({5, 6, 7}));
96}