Coverage Report

Created: 2026-04-12 06:58

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/qpdf/libqpdf/global.cc
Line
Count
Source
1
#include <qpdf/global_private.hh>
2
3
#include <qpdf/Util.hh>
4
5
using namespace qpdf;
6
using namespace qpdf::global;
7
8
Limits Limits::l;
9
Options Options::o;
10
11
void
12
Options::fuzz_mode(bool value)
13
0
{
14
0
    if (value) {
15
0
        o.fuzz_mode_ = true;
16
        // Limit the memory used to decompress JPEG files during fuzzing. Excessive memory use
17
        // during fuzzing is due to corrupt JPEG data which sometimes cannot be detected before
18
        // jpeg_start_decompress is called. During normal use of qpdf very large JPEGs can
19
        // occasionally occur legitimately and therefore must be allowed during normal operations.
20
0
        Limits::dct_max_memory(10'000'000);
21
0
        Limits::dct_max_progressive_scans(50);
22
        // Do not decompress corrupt data. This may cause extended runtime within jpeglib without
23
        // exercising additional code paths in qpdf.
24
0
        dct_throw_on_corrupt_data(true);
25
0
        Limits::png_max_memory(1'000'000);
26
0
        Limits::flate_max_memory(200'000);
27
0
        Limits::run_length_max_memory(1'000'000);
28
0
        Limits::tiff_max_memory(1'000'000);
29
        // Set a reasonable default maximum warnings per document for fuzzing to avoid time-outs due
30
        // to extensive recovery efforts.
31
0
        Limits::doc_max_warnings(200);
32
0
    }
33
0
}
34
35
void
36
Limits::parser_max_container_size(bool damaged, uint32_t value)
37
0
{
38
0
    if (damaged) {
39
0
        l.parser_max_container_size_damaged_set_ = true;
40
0
        l.parser_max_container_size_damaged_ = value;
41
0
    } else {
42
0
        l.parser_max_container_size_ = value;
43
0
    }
44
0
}
45
46
void
47
Limits::disable_defaults()
48
0
{
49
0
    if (!l.parser_max_errors_set_) {
50
0
        l.parser_max_errors_ = 0;
51
0
    }
52
0
    if (!l.parser_max_container_size_damaged_set_) {
53
0
        l.parser_max_container_size_damaged_ = std::numeric_limits<uint32_t>::max();
54
0
    }
55
0
    if (!l.max_stream_filters_set_) {
56
0
        l.max_stream_filters_ = std::numeric_limits<uint32_t>::max();
57
0
    }
58
0
}
59
60
qpdf_result_e
61
qpdf_global_get_uint32(qpdf_param_e param, uint32_t* value)
62
0
{
63
0
    qpdf_expect(value);
64
0
    switch (param) {
65
0
    case qpdf_p_inspection_mode:
66
0
        *value = Options::inspection_mode();
67
0
        return qpdf_r_ok;
68
0
    case qpdf_p_fuzz_mode:
69
0
        *value = Options::fuzz_mode();
70
0
        return qpdf_r_ok;
71
0
    case qpdf_p_default_limits:
72
0
        *value = Options::default_limits();
73
0
        return qpdf_r_ok;
74
0
    case qpdf_p_limit_errors:
75
0
        *value = Limits::errors();
76
0
        return qpdf_r_ok;
77
0
    case qpdf_p_dct_throw_on_corrupt_data:
78
0
        *value = Options::dct_throw_on_corrupt_data();
79
0
        return qpdf_r_ok;
80
0
    case qpdf_p_doc_max_warnings:
81
0
        *value = Limits::doc_max_warnings();
82
0
        return qpdf_r_ok;
83
0
    case qpdf_p_parser_max_nesting:
84
0
        *value = Limits::parser_max_nesting();
85
0
        return qpdf_r_ok;
86
0
    case qpdf_p_parser_max_errors:
87
0
        *value = Limits::parser_max_errors();
88
0
        return qpdf_r_ok;
89
0
    case qpdf_p_parser_max_container_size:
90
0
        *value = Limits::parser_max_container_size(false);
91
0
        return qpdf_r_ok;
92
0
    case qpdf_p_parser_max_container_size_damaged:
93
0
        *value = Limits::parser_max_container_size(true);
94
0
        return qpdf_r_ok;
95
0
    case qpdf_p_max_stream_filters:
96
0
        *value = Limits::max_stream_filters();
97
0
        return qpdf_r_ok;
98
0
    case qpdf_p_dct_max_memory:
99
0
        qpdf_invariant(util::fits<uint32_t>(Limits::dct_max_memory()));
100
0
        *value = static_cast<uint32_t>(Limits::dct_max_memory());
101
0
        return qpdf_r_ok;
102
0
    case qpdf_p_dct_max_progressive_scans:
103
0
        qpdf_invariant(util::fits<uint32_t>(Limits::dct_max_progressive_scans()));
104
0
        *value = static_cast<uint32_t>(Limits::dct_max_progressive_scans());
105
0
        return qpdf_r_ok;
106
0
    case qpdf_p_flate_max_memory:
107
0
        qpdf_invariant(util::fits<uint32_t>(Limits::flate_max_memory()));
108
0
        *value = static_cast<uint32_t>(Limits::flate_max_memory());
109
0
        return qpdf_r_ok;
110
0
    case qpdf_p_png_max_memory:
111
0
        qpdf_invariant(util::fits<uint32_t>(Limits::png_max_memory()));
112
0
        *value = static_cast<uint32_t>(Limits::png_max_memory());
113
0
        return qpdf_r_ok;
114
0
    case qpdf_p_run_length_max_memory:
115
0
        qpdf_invariant(util::fits<uint32_t>(Limits::run_length_max_memory()));
116
0
        *value = static_cast<uint32_t>(Limits::run_length_max_memory());
117
0
        return qpdf_r_ok;
118
0
    case qpdf_p_tiff_max_memory:
119
0
        qpdf_invariant(util::fits<uint32_t>(Limits::tiff_max_memory()));
120
0
        *value = static_cast<uint32_t>(Limits::tiff_max_memory());
121
0
        return qpdf_r_ok;
122
0
    default:
123
0
        return qpdf_r_bad_parameter;
124
0
    }
125
0
}
126
127
qpdf_result_e
128
qpdf_global_set_uint32(qpdf_param_e param, uint32_t value)
129
0
{
130
0
    switch (param) {
131
0
    case qpdf_p_inspection_mode:
132
0
        Options::inspection_mode(value);
133
0
        return qpdf_r_ok;
134
0
    case qpdf_p_fuzz_mode:
135
0
        Options::fuzz_mode(value);
136
0
        return qpdf_r_ok;
137
0
    case qpdf_p_default_limits:
138
0
        Options::default_limits(value);
139
0
        return qpdf_r_ok;
140
0
    case qpdf_p_dct_throw_on_corrupt_data:
141
0
        Options::dct_throw_on_corrupt_data(value);
142
0
        return qpdf_r_ok;
143
0
    case qpdf_p_doc_max_warnings:
144
0
        Limits::doc_max_warnings(value);
145
0
        return qpdf_r_ok;
146
0
    case qpdf_p_parser_max_nesting:
147
0
        Limits::parser_max_nesting(value);
148
0
        return qpdf_r_ok;
149
0
    case qpdf_p_parser_max_errors:
150
0
        Limits::parser_max_errors(value);
151
0
        return qpdf_r_ok;
152
0
    case qpdf_p_parser_max_container_size:
153
0
        Limits::parser_max_container_size(false, value);
154
0
        return qpdf_r_ok;
155
0
    case qpdf_p_parser_max_container_size_damaged:
156
0
        Limits::parser_max_container_size(true, value);
157
0
        return qpdf_r_ok;
158
0
    case qpdf_p_max_stream_filters:
159
0
        Limits::max_stream_filters(value);
160
0
        return qpdf_r_ok;
161
0
    case qpdf_p_dct_max_memory:
162
0
        Limits::dct_max_memory(util::fits<long>(value) ? static_cast<long>(value) : 0);
163
0
        return qpdf_r_ok;
164
0
    case qpdf_p_dct_max_progressive_scans:
165
0
        Limits::dct_max_progressive_scans(util::fits<int>(value) ? static_cast<int>(value) : 0);
166
0
        return qpdf_r_ok;
167
0
    case qpdf_p_flate_max_memory:
168
0
        Limits::flate_max_memory(value);
169
0
        return qpdf_r_ok;
170
0
    case qpdf_p_png_max_memory:
171
0
        Limits::png_max_memory(value);
172
0
        return qpdf_r_ok;
173
0
    case qpdf_p_run_length_max_memory:
174
0
        Limits::run_length_max_memory(value);
175
0
        return qpdf_r_ok;
176
0
    case qpdf_p_tiff_max_memory:
177
0
        Limits::tiff_max_memory(value);
178
0
        return qpdf_r_ok;
179
0
    default:
180
0
        return qpdf_r_bad_parameter;
181
0
    }
182
0
}