Coverage Report

Created: 2025-10-13 07:02

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libxlsxwriter/dev/fuzzing/xlsx_fuzzer.cpp
Line
Count
Source
1
#include <cstdint>
2
#include <unistd.h>
3
#include <fuzzer/FuzzedDataProvider.h>
4
5
#include "xlsxwriter.h"
6
7
const std::string mem_dir{"/dev/shm"};
8
const std::string file_template = "/fuzzXXXXXX";
9
char temp_file_dir[FILENAME_MAX] = {0};
10
11
/**
12
 * \brief: Performs all prep-work needed for continuous fuzzing
13
 * \return: Whether initialization was successful
14
 */
15
int init_for_fuzzing()
16
1
{
17
    // Initialize the temporary file directory, based off what is available on the system
18
19
1
    if (0 == access(mem_dir.c_str(), W_OK | R_OK))
20
1
    {
21
        // We can read and write to the in-memory directory
22
1
        memcpy(temp_file_dir, mem_dir.c_str(), strnlen(mem_dir.c_str(), FILENAME_MAX));
23
1
    }
24
0
    else
25
0
    {
26
        // Default to a temporary directory
27
0
        const char* tmp_prefix = getenv("TMPDIR");
28
0
        if (nullptr == tmp_prefix)
29
0
        {
30
0
            tmp_prefix = "/tmp";
31
0
        }
32
0
        memcpy((void*) temp_file_dir, tmp_prefix, strnlen(tmp_prefix, FILENAME_MAX));
33
0
    }
34
1
    return 0;
35
1
}
36
37
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, const size_t size)
38
1.34k
{
39
1.34k
    static bool init_fuzzing = init_for_fuzzing();
40
41
1.34k
    char fuzz_file[FILENAME_MAX + 1] = {0};
42
1.34k
    int fuzz_fd = 0;
43
1.34k
    int ret = -1;
44
1.34k
    ssize_t wc = 0;
45
1.34k
    size_t byte_len;
46
1.34k
    lxw_workbook *workbook = nullptr;
47
1.34k
    lxw_worksheet *worksheet = nullptr;
48
1.34k
    FuzzedDataProvider fdp{data, size};
49
1.34k
    std::vector<std::uint8_t> file_bytes{};
50
51
1.34k
    strncpy(fuzz_file, temp_file_dir, strlen(temp_file_dir));
52
1.34k
    strncat(fuzz_file, file_template.c_str(), file_template.length());
53
54
1.34k
    if ((fuzz_fd = mkstemp(fuzz_file)) < 0)
55
0
    {
56
0
        goto fail;
57
0
    }
58
59
1.34k
    byte_len = fdp.ConsumeIntegralInRange<size_t>(0, fdp.remaining_bytes());
60
1.34k
    file_bytes = fdp.ConsumeBytes<uint8_t>(byte_len);
61
1.34k
    write(fuzz_fd, file_bytes.data(), std::min(file_bytes.size(), byte_len));
62
63
1.34k
    workbook = workbook_new(fuzz_file);
64
1.34k
    worksheet = workbook_add_worksheet(workbook, nullptr);
65
66
7.45k
    for (int row = 0; row < fdp.ConsumeIntegralInRange(0, 25); ++row)
67
6.11k
    {
68
73.5k
        for (int col = 0; col < fdp.ConsumeIntegralInRange(0, 25); ++col)
69
67.4k
        {
70
67.4k
            worksheet_write_string(worksheet, row, col, fdp.ConsumeRandomLengthString().c_str(), nullptr);
71
67.4k
        }
72
6.11k
    }
73
74
1.34k
    ret = 0;
75
76
1.34k
    fail:
77
1.34k
    if (nullptr != workbook)
78
1.34k
    {
79
1.34k
        workbook_close(workbook);
80
1.34k
    }
81
1.34k
    close(fuzz_fd);
82
1.34k
    unlink(fuzz_file);
83
1.34k
    return ret;
84
1.34k
}