/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 | } |