Coverage Report

Created: 2025-07-01 06:10

/src/qpdf/libqpdf/QPDFOutlineObjectHelper.cc
Line
Count
Source (jump to first uncovered line)
1
#include <qpdf/QPDFOutlineObjectHelper.hh>
2
3
#include <qpdf/QPDFOutlineDocumentHelper.hh>
4
#include <qpdf/QTC.hh>
5
6
QPDFOutlineObjectHelper::Members::Members(QPDFOutlineDocumentHelper& dh) :
7
0
    dh(dh)
8
0
{
9
0
}
10
11
QPDFOutlineObjectHelper::QPDFOutlineObjectHelper(
12
    QPDFObjectHandle a_oh, QPDFOutlineDocumentHelper& dh, int depth) :
13
0
    QPDFObjectHelper(a_oh),
14
0
    m(new Members(dh))
15
0
{
16
0
    if (depth > 50) {
17
        // Not exercised in test suite, but was tested manually by temporarily changing max depth
18
        // to 1.
19
0
        return;
20
0
    }
21
0
    if (QPDFOutlineDocumentHelper::Accessor::checkSeen(m->dh, a_oh.getObjGen())) {
22
0
        QTC::TC("qpdf", "QPDFOutlineObjectHelper loop");
23
0
        return;
24
0
    }
25
26
0
    QPDFObjGen::set children;
27
0
    QPDFObjectHandle cur = a_oh.getKey("/First");
28
0
    while (!cur.isNull() && cur.isIndirect() && children.add(cur)) {
29
0
        QPDFOutlineObjectHelper new_ooh(cur, dh, 1 + depth);
30
0
        new_ooh.m->parent = std::make_shared<QPDFOutlineObjectHelper>(*this);
31
0
        m->kids.push_back(new_ooh);
32
0
        cur = cur.getKey("/Next");
33
0
    }
34
0
}
35
36
std::shared_ptr<QPDFOutlineObjectHelper>
37
QPDFOutlineObjectHelper::getParent()
38
0
{
39
0
    return m->parent;
40
0
}
41
42
std::vector<QPDFOutlineObjectHelper>
43
QPDFOutlineObjectHelper::getKids()
44
0
{
45
0
    return m->kids;
46
0
}
47
48
QPDFObjectHandle
49
QPDFOutlineObjectHelper::getDest()
50
0
{
51
0
    QPDFObjectHandle dest;
52
0
    QPDFObjectHandle A;
53
0
    if (oh().hasKey("/Dest")) {
54
0
        QTC::TC("qpdf", "QPDFOutlineObjectHelper direct dest");
55
0
        dest = oh().getKey("/Dest");
56
0
    } else if (
57
0
        (A = oh().getKey("/A")).isDictionary() && A.getKey("/S").isName() &&
58
0
        (A.getKey("/S").getName() == "/GoTo") && A.hasKey("/D")) {
59
0
        QTC::TC("qpdf", "QPDFOutlineObjectHelper action dest");
60
0
        dest = A.getKey("/D");
61
0
    }
62
0
    if (!dest) {
63
0
        return QPDFObjectHandle::newNull();
64
0
    }
65
66
0
    if (dest.isName() || dest.isString()) {
67
0
        QTC::TC("qpdf", "QPDFOutlineObjectHelper named dest");
68
0
        dest = m->dh.resolveNamedDest(dest);
69
0
    }
70
71
0
    return dest;
72
0
}
73
74
QPDFObjectHandle
75
QPDFOutlineObjectHelper::getDestPage()
76
0
{
77
0
    QPDFObjectHandle dest = getDest();
78
0
    if ((dest.isArray()) && (dest.getArrayNItems() > 0)) {
79
0
        return dest.getArrayItem(0);
80
0
    }
81
0
    return QPDFObjectHandle::newNull();
82
0
}
83
84
int
85
QPDFOutlineObjectHelper::getCount()
86
0
{
87
0
    int count = 0;
88
0
    if (oh().hasKey("/Count")) {
89
0
        count = oh().getKey("/Count").getIntValueAsInt();
90
0
    }
91
0
    return count;
92
0
}
93
94
std::string
95
QPDFOutlineObjectHelper::getTitle()
96
0
{
97
0
    std::string result;
98
0
    if (oh().hasKey("/Title")) {
99
0
        result = oh().getKey("/Title").getUTF8Value();
100
0
    }
101
0
    return result;
102
0
}