/src/miniz/tests/add_in_place_fuzzer.c
Line | Count | Source |
1 | | #include <stdio.h> |
2 | | #include <limits.h> |
3 | | #include "miniz.h" |
4 | | |
5 | | static const mz_uint files_count = 5; |
6 | | static const mz_uint max_file_size = 1024 * 1024; |
7 | | static const char *zip_file_name = "/tmp/miniz-fuzzer-test.zip"; |
8 | | |
9 | | /* Read 32-bit integer from the fuzzer input with range [0, max] */ |
10 | | static mz_uint read_uint32(const mz_uint8 **data, size_t *size, mz_uint max) |
11 | 28.0k | { |
12 | 28.0k | mz_uint value = 0; |
13 | | |
14 | 28.0k | if (*size >= sizeof(mz_uint)) |
15 | 22.1k | { |
16 | 22.1k | memcpy(&value, *data, sizeof(mz_uint)); |
17 | 22.1k | *data += sizeof(mz_uint); |
18 | 22.1k | *size -= sizeof(mz_uint); |
19 | 22.1k | value = MZ_MIN(max == UINT_MAX ? value : value % (max + 1), *size); |
20 | 22.1k | } |
21 | | |
22 | 28.0k | return value; |
23 | 28.0k | } |
24 | | |
25 | | /* Read random-length null terminated string from the fuzzer input */ |
26 | | static mz_bool read_string(const mz_uint8 **data, size_t *size, char *destination, mz_uint max_len) |
27 | 8.98k | { |
28 | 8.98k | mz_uint filename_len = read_uint32(data, size, max_len - 1); |
29 | 8.98k | memcpy(destination, *data, filename_len); |
30 | 8.98k | destination[filename_len] = 0; |
31 | 8.98k | *data += filename_len; |
32 | 8.98k | *size -= filename_len; |
33 | 8.98k | return filename_len > 0; |
34 | 8.98k | } |
35 | | |
36 | | /* Get random-length buffer from the fuzzer input */ |
37 | | static mz_bool read_buffer(const mz_uint8 **data, size_t *size, const mz_uint8 **destination, mz_uint *len) |
38 | 6.71k | { |
39 | 6.71k | *len = read_uint32(data, size, max_file_size); |
40 | 6.71k | *destination = *data; |
41 | 6.71k | *data += *len; |
42 | 6.71k | *size -= *len; |
43 | 6.71k | return *len > 0; |
44 | 6.71k | } |
45 | | |
46 | | int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) |
47 | 3.03k | { |
48 | 3.03k | mz_uint i; |
49 | 3.03k | char archive_file_name[FILENAME_MAX]; |
50 | 3.03k | const mz_uint8 *file_data; |
51 | 3.03k | mz_uint file_length, flags; |
52 | 3.03k | size_t extracted_size; |
53 | 3.03k | mz_uint8 *extracted_data; |
54 | 3.03k | const char *comment = mz_version(); |
55 | | |
56 | | /* Remove the temporary file for better reproducibility */ |
57 | 3.03k | remove(zip_file_name); |
58 | | |
59 | 9.19k | for (i = 0; i < files_count; ++i) |
60 | 8.98k | { |
61 | | /* Fill archive file name */ |
62 | 8.98k | if (!read_string(&data, &size, archive_file_name, sizeof(archive_file_name))) |
63 | 2.26k | { |
64 | 2.26k | break; |
65 | 2.26k | } |
66 | | |
67 | | /* Prepare file's content */ |
68 | 6.71k | if (!read_buffer(&data, &size, &file_data, &file_length)) |
69 | 564 | { |
70 | 564 | break; |
71 | 564 | } |
72 | | |
73 | | /* Prepare flags for adding file */ |
74 | 6.15k | flags = read_uint32(&data, &size, UINT_MAX); |
75 | | |
76 | 6.15k | mz_zip_add_mem_to_archive_file_in_place(zip_file_name, archive_file_name, file_data, file_length, comment, |
77 | 6.15k | (mz_uint16)strlen(comment), flags); |
78 | | |
79 | | /* Prepare flags for extracting file */ |
80 | 6.15k | flags = read_uint32(&data, &size, UINT_MAX); |
81 | 6.15k | extracted_data = mz_zip_extract_archive_file_to_heap(zip_file_name, archive_file_name, &extracted_size, flags); |
82 | 6.15k | free(extracted_data); |
83 | 6.15k | } |
84 | | |
85 | 3.03k | remove(zip_file_name); |
86 | 3.03k | return 0; |
87 | 3.03k | } |