Coverage Report

Created: 2026-06-07 08:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/poppler/qt6/tests/fuzzing/qt_signature_fuzzer.cc
Line
Count
Source
1
#include <cstdint>
2
#include <vector>
3
4
#include <poppler-qt6.h>
5
#include <poppler-converter.h>
6
#include <poppler-form.h>
7
8
#include <QtCore/QBuffer>
9
#include <QtCore/QTemporaryFile>
10
11
#include <unistd.h>
12
#include <libgen.h>
13
#include <linux/limits.h>
14
15
1.11k
static void dummy_error_function(const QString &, const QVariant &) { }
16
17
static void initialize_nss_dir()
18
1.11k
{
19
1.11k
    static bool initialized = false;
20
1.11k
    if (initialized) {
21
1.11k
        return;
22
1.11k
    }
23
24
1
    char exe_path[PATH_MAX];
25
1
    ssize_t len = readlink("/proc/self/exe", exe_path, sizeof(exe_path) - 1);
26
1
    if (len != -1) {
27
1
        exe_path[len] = '\0';
28
1
        char *dir_path = dirname(exe_path);
29
1
        const QString nssDir = QString::fromLocal8Bit(dir_path) + QStringLiteral("/unittestcases/signing_nss/db_complete");
30
1
        Poppler::setNSSDir(nssDir);
31
1
    }
32
33
1
    initialized = true;
34
1
}
35
36
static std::vector<uint8_t> createTestImage(const uint8_t *data, size_t size, uint8_t mode)
37
1.11k
{
38
1.11k
    std::vector<uint8_t> result;
39
40
1.11k
    switch (mode % 2) {
41
982
    case 0: {
42
982
        const uint8_t png_header[] = { 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a };
43
982
        result.insert(result.end(), png_header, png_header + sizeof(png_header));
44
982
        break;
45
0
    }
46
136
    case 1: {
47
136
        const uint8_t jpeg_header[] = { 0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46 };
48
136
        result.insert(result.end(), jpeg_header, jpeg_header + sizeof(jpeg_header));
49
136
        break;
50
0
    }
51
1.11k
    }
52
53
1.11k
    result.insert(result.end(), data, data + size);
54
1.11k
    return result;
55
1.11k
}
56
57
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
58
1.12k
{
59
1.12k
    if (size < 10) {
60
6
        return 0;
61
6
    }
62
63
1.11k
    Poppler::setDebugErrorFunction(dummy_error_function, QVariant());
64
1.11k
    initialize_nss_dir();
65
66
1.11k
    uint8_t mode = data[0];
67
1.11k
    std::vector<uint8_t> imageData = createTestImage(data + 1, size - 1, mode);
68
69
1.11k
    QTemporaryFile imageFile;
70
1.11k
    if (!imageFile.open()) {
71
0
        return 0;
72
0
    }
73
1.11k
    imageFile.write(reinterpret_cast<const char *>(imageData.data()), imageData.size());
74
1.11k
    imageFile.flush();
75
1.11k
    imageFile.close();
76
77
1.11k
    const char *minimalPdf =
78
1.11k
            "%PDF-1.4\n1 0 obj<</Type/Catalog/Pages 2 0 R>>endobj\n2 0 obj<</Type/Pages/Count 1/Kids[3 0 R]>>endobj\n3 0 obj<</Type/Page/Parent 2 0 R/MediaBox[0 0 612 792]>>endobj\nxref\n0 4\ntrailer<</Root 1 0 R/Size 4>>\n%%EOF";
79
80
1.11k
    QByteArray pdfBytes(minimalPdf);
81
1.11k
    std::unique_ptr<Poppler::Document> doc = Poppler::Document::loadFromData(pdfBytes);
82
1.11k
    if (!doc || doc->isLocked() || doc->numPages() == 0) {
83
0
        return 0;
84
0
    }
85
86
1.11k
    QTemporaryFile outputFile;
87
1.11k
    if (!outputFile.open()) {
88
0
        return 0;
89
0
    }
90
91
1.11k
    std::unique_ptr<Poppler::PDFConverter> converter = doc->pdfConverter();
92
1.11k
    if (!converter) {
93
0
        return 0;
94
0
    }
95
96
1.11k
    converter->setOutputFileName(outputFile.fileName());
97
98
1.11k
    Poppler::PDFConverter::NewSignatureData sigData;
99
1.11k
    sigData.setCertNickname(QStringLiteral("RSA test key 01"));
100
1.11k
    sigData.setPassword(QStringLiteral(""));
101
1.11k
    sigData.setPage(0);
102
1.11k
    sigData.setBoundingRectangle(QRectF(100, 100, 200, 100));
103
1.11k
    sigData.setSignatureText(QStringLiteral("Fuzz Test"));
104
1.11k
    sigData.setImagePath(imageFile.fileName());
105
106
1.11k
    converter->sign(sigData);
107
108
1.11k
    return 0;
109
1.11k
}