Coverage Report

Created: 2026-06-09 06:59

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/qpdf/fuzz/qpdf_fuzzer.cc
Line
Count
Source
1
#include <qpdf/Buffer.hh>
2
#include <qpdf/BufferInputSource.hh>
3
#include <qpdf/Pl_Discard.hh>
4
#include <qpdf/QPDF.hh>
5
#include <qpdf/QPDFWriter.hh>
6
#include <qpdf/QUtil.hh>
7
#include <qpdf/global.hh>
8
9
class FuzzHelper
10
{
11
  public:
12
    FuzzHelper(unsigned char const* data, size_t size) :
13
        // We do not modify data, so it is safe to remove the const for Buffer
14
21.3k
        input_buffer(const_cast<unsigned char*>(data), size)
15
21.3k
    {
16
21.3k
    }
17
18
    void
19
    run()
20
21.3k
    {
21
21.3k
        qpdf::global::options::fuzz_mode(true);
22
        // The goal here is that you should be able to throw anything at libqpdf and it will respond
23
        // without any memory errors and never do anything worse than throwing a QPDFExc or
24
        // std::runtime_error. Throwing any other kind of exception, segfaulting, or having a memory
25
        // error (when built with appropriate sanitizers) will all cause abnormal exit.
26
21.3k
        try {
27
21.3k
            std::cerr << "\ninfo: starting testWrite\n";
28
29
21.3k
            auto is = std::make_shared<BufferInputSource>("fuzz input", &input_buffer);
30
21.3k
            QPDF qpdf;
31
21.3k
            qpdf.processInputSource(is);
32
21.3k
            QPDFWriter w(qpdf);
33
21.3k
            w.setOutputPipeline(&discard);
34
21.3k
            w.setDecodeLevel(qpdf_dl_all);
35
21.3k
            w.setDeterministicID(true);
36
21.3k
            w.setQDFMode(true);
37
21.3k
            w.write();
38
21.3k
        } catch (std::runtime_error const& e) {
39
13.3k
            std::cerr << "runtime_error: " << e.what() << '\n';
40
13.3k
        }
41
21.3k
    }
42
43
  private:
44
    Buffer input_buffer;
45
    Pl_Discard discard;
46
};
47
48
extern "C" int
49
LLVMFuzzerTestOneInput(unsigned char const* data, size_t size)
50
21.3k
{
51
21.3k
#ifndef _WIN32
52
    // Used by jpeg library to work around false positives in memory sanitizer.
53
21.3k
    setenv("JSIMD_FORCENONE", "1", 1);
54
21.3k
#endif
55
21.3k
    FuzzHelper f(data, size);
56
21.3k
    f.run();
57
21.3k
    return 0;
58
21.3k
}