• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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