1 // Copyright 2016 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 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6 7 #ifndef CORE_FPDFAPI_PARSER_CPDF_DOCUMENT_H_ 8 #define CORE_FPDFAPI_PARSER_CPDF_DOCUMENT_H_ 9 10 #include <functional> 11 #include <memory> 12 #include <set> 13 #include <utility> 14 #include <vector> 15 16 #include "build/build_config.h" 17 #include "core/fpdfapi/parser/cpdf_object.h" 18 #include "core/fpdfapi/parser/cpdf_parser.h" 19 #include "core/fxcrt/observed_ptr.h" 20 #include "core/fxcrt/retain_ptr.h" 21 #include "core/fxcrt/unowned_ptr.h" 22 23 class CFX_Matrix; 24 class CPDF_LinearizedHeader; 25 class CPDF_Object; 26 class CPDF_ReadValidator; 27 class CPDF_StreamAcc; 28 class IFX_SeekableReadStream; 29 class JBig2_DocumentContext; 30 31 #define FPDFPERM_MODIFY 0x0008 32 #define FPDFPERM_ANNOT_FORM 0x0020 33 #define FPDFPERM_FILL_FORM 0x0100 34 #define FPDFPERM_EXTRACT_ACCESS 0x0200 35 36 class CPDF_Document : public Observable, 37 public CPDF_Parser::ParsedObjectsHolder { 38 public: 39 // Type from which the XFA extension can subclass itself. 40 class Extension { 41 public: 42 virtual ~Extension() = default; 43 virtual CPDF_Document* GetPDFDoc() const = 0; 44 virtual int GetPageCount() const = 0; 45 virtual void DeletePage(int page_index) = 0; 46 virtual uint32_t GetUserPermissions() const = 0; 47 virtual bool ContainsExtensionForm() const = 0; 48 virtual bool ContainsExtensionFullForm() const = 0; 49 virtual bool ContainsExtensionForegroundForm() const = 0; 50 }; 51 52 class LinkListIface { 53 public: 54 // CPDF_Document merely helps manage the lifetime. 55 virtual ~LinkListIface() = default; 56 }; 57 58 class PageDataIface { 59 public: 60 PageDataIface(); 61 virtual ~PageDataIface(); 62 63 virtual void ClearStockFont() = 0; 64 virtual RetainPtr<CPDF_StreamAcc> GetFontFileStreamAcc( 65 const CPDF_Stream* pFontStream) = 0; 66 virtual void MaybePurgeFontFileStreamAcc( 67 const CPDF_Stream* pFontStream) = 0; 68 SetDocument(CPDF_Document * pDoc)69 void SetDocument(CPDF_Document* pDoc) { m_pDoc = pDoc; } GetDocument()70 CPDF_Document* GetDocument() const { return m_pDoc.Get(); } 71 72 private: 73 UnownedPtr<CPDF_Document> m_pDoc; 74 }; 75 76 class RenderDataIface { 77 public: 78 RenderDataIface(); 79 virtual ~RenderDataIface(); 80 SetDocument(CPDF_Document * pDoc)81 void SetDocument(CPDF_Document* pDoc) { m_pDoc = pDoc; } GetDocument()82 CPDF_Document* GetDocument() const { return m_pDoc.Get(); } 83 84 private: 85 UnownedPtr<CPDF_Document> m_pDoc; 86 }; 87 88 static const int kPageMaxNum = 0xFFFFF; 89 90 CPDF_Document(std::unique_ptr<RenderDataIface> pRenderData, 91 std::unique_ptr<PageDataIface> pPageData); 92 ~CPDF_Document() override; 93 GetExtension()94 Extension* GetExtension() const { return m_pExtension.get(); } SetExtension(std::unique_ptr<Extension> pExt)95 void SetExtension(std::unique_ptr<Extension> pExt) { 96 m_pExtension = std::move(pExt); 97 } 98 GetParser()99 CPDF_Parser* GetParser() const { return m_pParser.get(); } GetRoot()100 CPDF_Dictionary* GetRoot() const { return m_pRootDict.Get(); } 101 CPDF_Dictionary* GetInfo(); 102 103 void DeletePage(int iPage); 104 int GetPageCount() const; 105 bool IsPageLoaded(int iPage) const; 106 CPDF_Dictionary* GetPageDictionary(int iPage); 107 int GetPageIndex(uint32_t objnum); 108 uint32_t GetUserPermissions() const; 109 110 // Returns a valid pointer, unless it is called during destruction. GetPageData()111 PageDataIface* GetPageData() const { return m_pDocPage.get(); } GetRenderData()112 RenderDataIface* GetRenderData() const { return m_pDocRender.get(); } 113 114 void SetPageObjNum(int iPage, uint32_t objNum); 115 CodecContext()116 std::unique_ptr<JBig2_DocumentContext>* CodecContext() { 117 return &m_pCodecContext; 118 } GetLinksContext()119 LinkListIface* GetLinksContext() const { return m_pLinksContext.get(); } SetLinksContext(std::unique_ptr<LinkListIface> pContext)120 void SetLinksContext(std::unique_ptr<LinkListIface> pContext) { 121 m_pLinksContext = std::move(pContext); 122 } 123 124 // CPDF_Parser::ParsedObjectsHolder overrides: 125 bool TryInit() override; 126 127 CPDF_Parser::Error LoadDoc( 128 const RetainPtr<IFX_SeekableReadStream>& pFileAccess, 129 const char* password); 130 CPDF_Parser::Error LoadLinearizedDoc( 131 const RetainPtr<CPDF_ReadValidator>& validator, 132 const char* password); has_valid_cross_reference_table()133 bool has_valid_cross_reference_table() const { 134 return m_bHasValidCrossReferenceTable; 135 } 136 137 void LoadPages(); 138 void CreateNewDoc(); 139 CPDF_Dictionary* CreateNewPage(int iPage); 140 IncrementParsedPageCount()141 void IncrementParsedPageCount() { ++m_ParsedPageCount; } GetParsedPageCountForTesting()142 uint32_t GetParsedPageCountForTesting() { return m_ParsedPageCount; } 143 144 protected: 145 class StockFontClearer { 146 public: 147 explicit StockFontClearer(CPDF_Document::PageDataIface* pPageData); 148 ~StockFontClearer(); 149 150 private: 151 UnownedPtr<CPDF_Document::PageDataIface> const m_pPageData; 152 }; 153 154 // Retrieve page count information by getting count value from the tree nodes 155 int RetrievePageCount(); 156 // When this method is called, m_pTreeTraversal[level] exists. 157 CPDF_Dictionary* TraversePDFPages(int iPage, int* nPagesToGo, size_t level); 158 int FindPageIndex(const CPDF_Dictionary* pNode, 159 uint32_t* skip_count, 160 uint32_t objnum, 161 int* index, 162 int level) const; 163 RetainPtr<CPDF_Object> ParseIndirectObject(uint32_t objnum) override; 164 const CPDF_Dictionary* GetPagesDict() const; 165 CPDF_Dictionary* GetPagesDict(); 166 bool InsertDeletePDFPage(CPDF_Dictionary* pPages, 167 int nPagesToGo, 168 CPDF_Dictionary* pPageDict, 169 bool bInsert, 170 std::set<CPDF_Dictionary*>* pVisited); 171 bool InsertNewPage(int iPage, CPDF_Dictionary* pPageDict); 172 void ResetTraversal(); 173 void SetParser(std::unique_ptr<CPDF_Parser> pParser); 174 CPDF_Parser::Error HandleLoadResult(CPDF_Parser::Error error); 175 176 std::unique_ptr<CPDF_Parser> m_pParser; 177 RetainPtr<CPDF_Dictionary> m_pRootDict; 178 RetainPtr<CPDF_Dictionary> m_pInfoDict; 179 180 // Vector of pairs to know current position in the page tree. The index in the 181 // vector corresponds to the level being described. The pair contains a 182 // pointer to the dictionary being processed at the level, and an index of the 183 // of the child being processed within the dictionary's /Kids array. 184 std::vector<std::pair<CPDF_Dictionary*, size_t>> m_pTreeTraversal; 185 186 // True if the CPDF_Parser succeeded without having to rebuild the cross 187 // reference table. 188 bool m_bHasValidCrossReferenceTable = false; 189 190 // Index of the next page that will be traversed from the page tree. 191 bool m_bReachedMaxPageLevel = false; 192 int m_iNextPageToTraverse = 0; 193 uint32_t m_ParsedPageCount = 0; 194 195 std::unique_ptr<RenderDataIface> m_pDocRender; 196 std::unique_ptr<PageDataIface> m_pDocPage; // Must be after |m_pDocRender|. 197 std::unique_ptr<JBig2_DocumentContext> m_pCodecContext; 198 std::unique_ptr<LinkListIface> m_pLinksContext; 199 std::vector<uint32_t> m_PageList; // Page number to page's dict objnum. 200 201 // Must be second to last. 202 StockFontClearer m_StockFontClearer; 203 204 // Must be last. Destroy the extension before any non-extension teardown. 205 std::unique_ptr<Extension> m_pExtension; 206 }; 207 208 #endif // CORE_FPDFAPI_PARSER_CPDF_DOCUMENT_H_ 209