Coverage Report

Created: 2026-08-11 07:29

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/poppler/poppler/Catalog.h
Line
Count
Source
1
//========================================================================
2
//
3
// Catalog.h
4
//
5
// Copyright 1996-2007 Glyph & Cog, LLC
6
//
7
//========================================================================
8
9
//========================================================================
10
//
11
// Modified under the Poppler project - http://poppler.freedesktop.org
12
//
13
// All changes made under the Poppler project to this file are licensed
14
// under GPL version 2 or later
15
//
16
// Copyright (C) 2005 Kristian Høgsberg <krh@redhat.com>
17
// Copyright (C) 2005, 2007, 2009-2011, 2013, 2017-2026 Albert Astals Cid <aacid@kde.org>
18
// Copyright (C) 2005 Jonathan Blandford <jrb@redhat.com>
19
// Copyright (C) 2005, 2006, 2008 Brad Hards <bradh@frogmouth.net>
20
// Copyright (C) 2007 Julien Rebetez <julienr@svn.gnome.org>
21
// Copyright (C) 2008, 2011 Pino Toscano <pino@kde.org>
22
// Copyright (C) 2010 Hib Eris <hib@hiberis.nl>
23
// Copyright (C) 2012 Fabio D'Urso <fabiodurso@hotmail.it>
24
// Copyright (C) 2013 Thomas Freitag <Thomas.Freitag@alfa.de>
25
// Copyright (C) 2013 Adrian Perez de Castro <aperez@igalia.com>
26
// Copyright (C) 2013, 2017 Adrian Johnson <ajohnson@redneon.com>
27
// Copyright (C) 2013 José Aliste <jaliste@src.gnome.org>
28
// Copyright (C) 2016 Masamichi Hosoda <trueroad@trueroad.jp>
29
// Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, <info@kdab.com>. Work sponsored by the LiMux project of the city of Munich
30
// Copyright (C) 2018 Adam Reichold <adam.reichold@t-online.de>
31
// Copyright (C) 2020 Oliver Sander <oliver.sander@tu-dresden.de>
32
// Copyright (C) 2020 Katarina Behrens <Katarina.Behrens@cib.de>
33
// Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, <info@kdab.com>. Work sponsored by Technische Universität Dresden
34
// Copyright (C) 2021 RM <rm+git@arcsin.org>
35
// Copyright (C) 2024-2026 g10 Code GmbH, Author: Sune Stolborg Vuorela <sune@vuorela.dk>
36
// Copyright (C) 2024 Hubert Figuière <hub@figuiere.net>
37
// Copyright (C) 2025 Trystan Mata <trystan.mata@tytanium.xyz>
38
//
39
// To see a description of the changes please see the Changelog file that
40
// came with your tarball or type make ChangeLog if you are building from git
41
//
42
//========================================================================
43
44
#ifndef CATALOG_H
45
#define CATALOG_H
46
47
#include "poppler-config.h"
48
#include "poppler_private_export.h"
49
#include "Object.h"
50
#include "Link.h"
51
#include "GfxState.h"
52
53
#include <memory>
54
#include <optional>
55
#include <unordered_map>
56
#include <vector>
57
58
class PDFDoc;
59
class XRef;
60
class Object;
61
class Page;
62
class PageAttrs;
63
struct Ref;
64
class PageLabelInfo;
65
class Form;
66
class OCGs;
67
class ViewerPreferences;
68
class FileSpec;
69
class StructTreeRoot;
70
71
//------------------------------------------------------------------------
72
// NameTree
73
//------------------------------------------------------------------------
74
75
class POPPLER_PRIVATE_EXPORT NameTree
76
{
77
public:
78
    NameTree();
79
    ~NameTree();
80
81
    NameTree(const NameTree &) = delete;
82
    NameTree &operator=(const NameTree &) = delete;
83
84
    void init(XRef *xref, Object *tree);
85
    Object lookup(const GooString *name);
86
4.82k
    int numEntries() { return entries.size(); };
87
    // iterator accessor, note it returns a pointer to the internal object, do not free nor delete it
88
    Object *getValue(int i);
89
    const GooString *getName(int i) const;
90
91
private:
92
    struct Entry
93
    {
94
        Entry(const Array &array, int index);
95
        ~Entry();
96
        GooString name;
97
        Object value;
98
    };
99
100
    void parse(const Object *tree, RefRecursionChecker &seen);
101
102
    XRef *xref;
103
    std::vector<std::unique_ptr<Entry>> entries;
104
};
105
106
//------------------------------------------------------------------------
107
// Catalog
108
//------------------------------------------------------------------------
109
110
class POPPLER_PRIVATE_EXPORT Catalog
111
{
112
public:
113
    // Constructor.
114
    explicit Catalog(PDFDoc *docA);
115
116
    // Destructor.
117
    ~Catalog();
118
119
    Catalog(const Catalog &) = delete;
120
    Catalog &operator=(const Catalog &) = delete;
121
122
    // Is catalog valid?
123
6.82k
    bool isOk() const { return ok; }
124
125
    // Get number of pages.
126
    int getNumPages();
127
128
    // Get a page.
129
    Page *getPage(int i);
130
131
    // Get the reference for a page object.
132
    Ref *getPageRef(int i);
133
134
    // Return base URI, or NULL if none.
135
0
    const std::optional<std::string> &getBaseURI() const { return baseURI; }
136
137
    // Return the contents of the metadata stream, or nullopt if there is
138
    // no metadata.
139
    std::optional<std::string> readMetadata();
140
141
    // Return the structure tree root object.
142
    StructTreeRoot *getStructTreeRoot();
143
144
    // Return values from the MarkInfo dictionary as flags in a bitfield.
145
    enum MarkInfoFlags
146
    {
147
        markInfoNull = 1 << 0,
148
        markInfoMarked = 1 << 1,
149
        markInfoUserProperties = 1 << 2,
150
        markInfoSuspects = 1 << 3,
151
    };
152
    unsigned int getMarkInfo();
153
154
    // Find a page, given its object ID.  Returns page number, or 0 if
155
    // not found.
156
    int findPage(Ref pageRef);
157
158
    // Find a named destination.  Returns the link destination, or
159
    // NULL if <name> is not a destination.
160
    std::unique_ptr<LinkDest> findDest(const GooString *name);
161
162
    Object *getDests();
163
164
    // Get the number of named destinations in name-dict
165
    int numDests();
166
167
    // Get the i'th named destination name in name-dict
168
    const char *getDestsName(int i);
169
170
    // Get the i'th named destination link destination in name-dict
171
    std::unique_ptr<LinkDest> getDestsDest(int i);
172
173
    // Get the number of named destinations in name-tree
174
0
    int numDestNameTree() { return getDestNameTree()->numEntries(); }
175
176
    // Get the i'th named destination name in name-tree
177
0
    const GooString *getDestNameTreeName(int i) { return getDestNameTree()->getName(i); }
178
179
    // Get the i'th named destination link destination in name-tree
180
    std::unique_ptr<LinkDest> getDestNameTreeDest(int i);
181
182
    // Get the number of embedded files
183
4.82k
    int numEmbeddedFiles() { return getEmbeddedFileNameTree()->numEntries(); }
184
185
    // Get the i'th file embedded (at the Document level) in the document
186
    std::unique_ptr<FileSpec> embeddedFile(int i);
187
188
    // Is there an embedded file with the given name?
189
    bool hasEmbeddedFile(const std::string &fileName);
190
191
    // Adds and embeddedFile
192
    // If there is already an existing embedded file with the given fileName
193
    // it gets replaced, if that's not what you want check hasEmbeddedFile first
194
    void addEmbeddedFile(GooFile *file, const std::string &fileName);
195
196
    // Get the number of javascript scripts
197
0
    int numJS() { return getJSNameTree()->numEntries(); }
198
0
    const GooString *getJSName(int i) { return getJSNameTree()->getName(i); }
199
200
    // Get the i'th JavaScript script (at the Document level) in the document
201
    std::string getJS(int i);
202
203
    // Convert between page indices and page labels.
204
    bool labelToIndex(const std::string &label, int *index);
205
    bool indexToLabel(int index, std::string *label);
206
207
    Object *getOutline();
208
    // returns the existing outline or new one if it doesn't exist
209
    Object *getCreateOutline();
210
211
0
    Object *getAcroForm() { return &acroForm; }
212
    void addFormToAcroForm(Ref formRef);
213
    void removeFormFromAcroForm(Ref formRef);
214
    void setAcroFormModified();
215
216
35.4k
    const OCGs *getOptContentConfig() { return optContent.get(); }
217
218
0
    int getPDFMajorVersion() const { return catalogPdfMajorVersion; }
219
0
    int getPDFMinorVersion() const { return catalogPdfMinorVersion; }
220
221
    enum FormType
222
    {
223
        NoForm,
224
        AcroForm,
225
        XfaForm
226
    };
227
228
    FormType getFormType();
229
    // This can return nullptr if the document is in a very damaged state
230
    Form *getCreateForm();
231
    Form *getForm();
232
233
    ViewerPreferences *getViewerPreferences();
234
235
    enum PageMode
236
    {
237
        pageModeNone,
238
        pageModeOutlines,
239
        pageModeThumbs,
240
        pageModeFullScreen,
241
        pageModeOC,
242
        pageModeAttach,
243
        pageModeNull
244
    };
245
    enum PageLayout
246
    {
247
        pageLayoutNone,
248
        pageLayoutSinglePage,
249
        pageLayoutOneColumn,
250
        pageLayoutTwoColumnLeft,
251
        pageLayoutTwoColumnRight,
252
        pageLayoutTwoPageLeft,
253
        pageLayoutTwoPageRight,
254
        pageLayoutNull
255
    };
256
257
    // Returns the page mode.
258
    PageMode getPageMode();
259
    PageLayout getPageLayout();
260
261
    enum DocumentAdditionalActionsType
262
    {
263
        actionCloseDocument, ///< Performed before closing the document
264
        actionSaveDocumentStart, ///< Performed before saving the document
265
        actionSaveDocumentFinish, ///< Performed after saving the document
266
        actionPrintDocumentStart, ///< Performed before printing the document
267
        actionPrintDocumentFinish, ///< Performed after printing the document
268
    };
269
270
    std::unique_ptr<LinkAction> getAdditionalAction(DocumentAdditionalActionsType type);
271
272
    std::unique_ptr<LinkAction> getOpenAction() const;
273
274
#if USE_CMS
275
    GfxLCMSProfilePtr getDisplayProfile();
276
    std::shared_ptr<GfxXYZ2DisplayTransforms> getXYZ2DisplayTransforms();
277
#endif
278
279
private:
280
    // Get page label info.
281
    PageLabelInfo *getPageLabelInfo();
282
283
    PDFDoc *doc;
284
    XRef *xref; // the xref table for this PDF file
285
    std::vector<std::pair<std::unique_ptr<Page>, Ref>> pages;
286
    std::unordered_map<Ref, std::size_t> refPageMap;
287
    std::vector<Object> *pagesList;
288
    std::vector<Ref> *pagesRefList;
289
    std::vector<std::unique_ptr<PageAttrs>> attrsList;
290
    std::vector<int> *kidsIdxList;
291
    Form *form;
292
    ViewerPreferences *viewerPrefs;
293
    int numPages; // number of pages
294
    Object dests; // named destination dictionary
295
    Object names; // named names dictionary
296
    NameTree *destNameTree; // named destination name-tree
297
    NameTree *embeddedFileNameTree; // embedded file name-tree
298
    NameTree *jsNameTree; // Java Script name-tree
299
    std::optional<std::string> baseURI; // base URI for URI-type links
300
    Object metadata; // metadata stream
301
    StructTreeRoot *structTreeRoot; // structure tree root
302
    unsigned int markInfo; // Flags from MarkInfo dictionary
303
    Object outline; // outline dictionary
304
    Object acroForm; // AcroForm dictionary
305
    Object viewerPreferences; // ViewerPreference dictionary
306
    std::unique_ptr<OCGs> optContent; // Optional Content groups
307
    bool ok; // true if catalog is valid
308
    PageLabelInfo *pageLabelInfo; // info about page labels
309
    PageMode pageMode; // page mode
310
    PageLayout pageLayout; // page layout
311
    Object additionalActions; // page additional actions
312
313
    bool initPageList(); // init the page list. called by cachePageTree.
314
    bool cacheSubTree(); // called by cachePageTree.
315
    bool cachePageTree(int page); // Cache first <page> pages.
316
    std::size_t cachePageTreeForRef(Ref pageRef); // Cache until <pageRef>.
317
    Object *findDestInTree(Object *tree, GooString *name, Object *obj);
318
319
    Object *getNames();
320
    NameTree *getDestNameTree();
321
    NameTree *getEmbeddedFileNameTree();
322
    NameTree *getJSNameTree();
323
    static std::unique_ptr<LinkDest> createLinkDest(Object *obj);
324
325
    int catalogPdfMajorVersion = -1;
326
    int catalogPdfMinorVersion = -1;
327
328
    mutable std::recursive_mutex mutex;
329
330
#if USE_CMS
331
    GfxLCMSProfilePtr displayProfile;
332
    std::shared_ptr<GfxXYZ2DisplayTransforms> XYZ2DisplayTransforms;
333
#endif
334
};
335
336
#endif