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 "public/fpdf_catalog.h"
6 
7 #include <memory>
8 
9 #include "core/fpdfapi/page/cpdf_docpagedata.h"
10 #include "core/fpdfapi/page/cpdf_pagemodule.h"
11 #include "core/fpdfapi/parser/cpdf_dictionary.h"
12 #include "core/fpdfapi/parser/cpdf_document.h"
13 #include "core/fpdfapi/parser/cpdf_number.h"
14 #include "core/fpdfapi/parser/cpdf_parser.h"
15 #include "core/fpdfapi/parser/cpdf_string.h"
16 #include "core/fpdfapi/render/cpdf_docrenderdata.h"
17 #include "fpdfsdk/cpdfsdk_helpers.h"
18 #include "public/cpp/fpdf_scopers.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20 
21 class CPDF_TestDocument final : public CPDF_Document {
22  public:
CPDF_TestDocument()23   CPDF_TestDocument()
24       : CPDF_Document(std::make_unique<CPDF_DocRenderData>(),
25                       std::make_unique<CPDF_DocPageData>()) {}
26 
SetRoot(CPDF_Dictionary * root)27   void SetRoot(CPDF_Dictionary* root) { SetRootForTesting(root); }
28 };
29 
30 class PDFCatalogTest : public testing::Test {
31  public:
SetUp()32   void SetUp() override {
33     CPDF_PageModule::Create();
34     auto pTestDoc = std::make_unique<CPDF_TestDocument>();
35     m_pDoc.reset(FPDFDocumentFromCPDFDocument(pTestDoc.release()));
36     m_pRootObj = pdfium::MakeRetain<CPDF_Dictionary>();
37   }
38 
TearDown()39   void TearDown() override {
40     m_pDoc.reset();
41     CPDF_PageModule::Destroy();
42   }
43 
44  protected:
45   ScopedFPDFDocument m_pDoc;
46   RetainPtr<CPDF_Dictionary> m_pRootObj;
47 };
48 
TEST_F(PDFCatalogTest,IsTagged)49 TEST_F(PDFCatalogTest, IsTagged) {
50   // Null doc
51   EXPECT_FALSE(FPDFCatalog_IsTagged(nullptr));
52 
53   CPDF_TestDocument* pTestDoc = static_cast<CPDF_TestDocument*>(
54       CPDFDocumentFromFPDFDocument(m_pDoc.get()));
55 
56   // No root
57   pTestDoc->SetRoot(nullptr);
58   EXPECT_FALSE(FPDFCatalog_IsTagged(m_pDoc.get()));
59 
60   // Empty root
61   pTestDoc->SetRoot(m_pRootObj.Get());
62   EXPECT_FALSE(FPDFCatalog_IsTagged(m_pDoc.get()));
63 
64   // Root with other key
65   m_pRootObj->SetNewFor<CPDF_String>("OTHER_KEY", "other value", false);
66   EXPECT_FALSE(FPDFCatalog_IsTagged(m_pDoc.get()));
67 
68   // Root with empty MarkInfo
69   CPDF_Dictionary* markInfoDict =
70       m_pRootObj->SetNewFor<CPDF_Dictionary>("MarkInfo");
71   EXPECT_FALSE(FPDFCatalog_IsTagged(m_pDoc.get()));
72 
73   // MarkInfo present but Marked is 0
74   markInfoDict->SetNewFor<CPDF_Number>("Marked", 0);
75   EXPECT_FALSE(FPDFCatalog_IsTagged(m_pDoc.get()));
76 
77   // MarkInfo present and Marked is 1, PDF is considered tagged.
78   markInfoDict->SetNewFor<CPDF_Number>("Marked", 1);
79   EXPECT_TRUE(FPDFCatalog_IsTagged(m_pDoc.get()));
80 }
81