File: xlsx_fuzzer.cpp

package info (click to toggle)
libxlsxwriter 1.2.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 37,864 kB
  • sloc: ansic: 65,601; python: 2,106; makefile: 693; perl: 229; sh: 224; xml: 168; cpp: 73; javascript: 5
file content (84 lines) | stat: -rw-r--r-- 2,372 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include <cstdint>
#include <unistd.h>
#include <fuzzer/FuzzedDataProvider.h>

#include "xlsxwriter.h"

const std::string mem_dir{"/dev/shm"};
const std::string file_template = "/fuzzXXXXXX";
char temp_file_dir[FILENAME_MAX] = {0};

/**
 * \brief: Performs all prep-work needed for continuous fuzzing
 * \return: Whether initialization was successful
 */
int init_for_fuzzing()
{
    // Initialize the temporary file directory, based off what is available on the system

    if (0 == access(mem_dir.c_str(), W_OK | R_OK))
    {
        // We can read and write to the in-memory directory
        memcpy(temp_file_dir, mem_dir.c_str(), strnlen(mem_dir.c_str(), FILENAME_MAX));
    }
    else
    {
        // Default to a temporary directory
        const char* tmp_prefix = getenv("TMPDIR");
        if (nullptr == tmp_prefix)
        {
            tmp_prefix = "/tmp";
        }
        memcpy((void*) temp_file_dir, tmp_prefix, strnlen(tmp_prefix, FILENAME_MAX));
    }
    return 0;
}

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, const size_t size)
{
    static bool init_fuzzing = init_for_fuzzing();

    char fuzz_file[FILENAME_MAX + 1] = {0};
    int fuzz_fd = 0;
    int ret = -1;
    ssize_t wc = 0;
    size_t byte_len;
    lxw_workbook *workbook = nullptr;
    lxw_worksheet *worksheet = nullptr;
    FuzzedDataProvider fdp{data, size};
    std::vector<std::uint8_t> file_bytes{};

    strncpy(fuzz_file, temp_file_dir, strlen(temp_file_dir));
    strncat(fuzz_file, file_template.c_str(), file_template.length());

    if ((fuzz_fd = mkstemp(fuzz_file)) < 0)
    {
        goto fail;
    }

    byte_len = fdp.ConsumeIntegralInRange<size_t>(0, fdp.remaining_bytes());
    file_bytes = fdp.ConsumeBytes<uint8_t>(byte_len);
    write(fuzz_fd, file_bytes.data(), std::min(file_bytes.size(), byte_len));

    workbook = workbook_new(fuzz_file);
    worksheet = workbook_add_worksheet(workbook, nullptr);

    for (int row = 0; row < fdp.ConsumeIntegralInRange(0, 25); ++row)
    {
        for (int col = 0; col < fdp.ConsumeIntegralInRange(0, 25); ++col)
        {
            worksheet_write_string(worksheet, row, col, fdp.ConsumeRandomLengthString().c_str(), nullptr);
        }
    }

    ret = 0;

    fail:
    if (nullptr != workbook)
    {
        workbook_close(workbook);
    }
    close(fuzz_fd);
    unlink(fuzz_file);
    return ret;
}