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 #include "third_party/base/ptr_util.h"
21 
22 class CPDF_TestDocument final : public CPDF_Document {
23  public:
CPDF_TestDocument()24   CPDF_TestDocument()
25       : CPDF_Document(pdfium::MakeUnique<CPDF_DocRenderData>(),
26                       pdfium::MakeUnique<CPDF_DocPageData>()) {}
27 
SetRoot(CPDF_Dictionary * root)28   void SetRoot(CPDF_Dictionary* root) { m_pRootDict.Reset(root); }
29 };
30 
31 class PDFCatalogTest : public testing::Test {
32  public:
SetUp()33   void SetUp() override {
34     CPDF_PageModule::Create();
35     auto pTestDoc = pdfium::MakeUnique<CPDF_TestDocument>();
36     m_pDoc.reset(FPDFDocumentFromCPDFDocument(pTestDoc.release()));
37     m_pRootObj = pdfium::MakeRetain<CPDF_Dictionary>();
38   }
39 
TearDown()40   void TearDown() override {
41     m_pDoc.reset();
42     CPDF_PageModule::Destroy();
43   }
44 
45  protected:
46   ScopedFPDFDocument m_pDoc;
47   RetainPtr<CPDF_Dictionary> m_pRootObj;
48 };
49 
TEST_F(PDFCatalogTest,IsTagged)50 TEST_F(PDFCatalogTest, IsTagged) {
51   // Null doc
52   EXPECT_FALSE(FPDFCatalog_IsTagged(nullptr));
53 
54   CPDF_TestDocument* pTestDoc = static_cast<CPDF_TestDocument*>(
55       CPDFDocumentFromFPDFDocument(m_pDoc.get()));
56 
57   // No root
58   pTestDoc->SetRoot(nullptr);
59   EXPECT_FALSE(FPDFCatalog_IsTagged(m_pDoc.get()));
60 
61   // Empty root
62   pTestDoc->SetRoot(m_pRootObj.Get());
63   EXPECT_FALSE(FPDFCatalog_IsTagged(m_pDoc.get()));
64 
65   // Root with other key
66   m_pRootObj->SetNewFor<CPDF_String>("OTHER_KEY", "other value", false);
67   EXPECT_FALSE(FPDFCatalog_IsTagged(m_pDoc.get()));
68 
69   // Root with empty MarkInfo
70   CPDF_Dictionary* markInfoDict =
71       m_pRootObj->SetNewFor<CPDF_Dictionary>("MarkInfo");
72   EXPECT_FALSE(FPDFCatalog_IsTagged(m_pDoc.get()));
73 
74   // MarkInfo present but Marked is 0
75   markInfoDict->SetNewFor<CPDF_Number>("Marked", 0);
76   EXPECT_FALSE(FPDFCatalog_IsTagged(m_pDoc.get()));
77 
78   // MarkInfo present and Marked is 1, PDF is considered tagged.
79   markInfoDict->SetNewFor<CPDF_Number>("Marked", 1);
80   EXPECT_TRUE(FPDFCatalog_IsTagged(m_pDoc.get()));
81 }
82