/src/minizip-ng/test/fuzz/zip_fuzzer.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* zip_fuzzer.c - Zip fuzzer for libFuzzer |
2 | | part of the minizip-ng project |
3 | | |
4 | | Copyright (C) 2018 The Chromium Authors |
5 | | Copyright (C) 2018 Anand K. Mistry |
6 | | Copyright (C) Nathan Moinvaziri |
7 | | https://github.com/zlib-ng/minizip-ng |
8 | | |
9 | | This program is distributed under the terms of the same license as zlib. |
10 | | See the accompanying LICENSE file for the full text of the license. |
11 | | */ |
12 | | |
13 | | #include "mz.h" |
14 | | #include "mz_strm.h" |
15 | | #include "mz_strm_mem.h" |
16 | | #include "mz_zip.h" |
17 | | |
18 | | #ifdef __cplusplus |
19 | | extern "C" { |
20 | | #endif |
21 | | |
22 | | /***************************************************************************/ |
23 | | |
24 | 1.31k | #define MZ_FUZZ_TEST_FILENAME "foo" |
25 | 190 | #define MZ_FUZZ_TEST_PWD "test123" |
26 | | |
27 | | /***************************************************************************/ |
28 | | |
29 | 437 | int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { |
30 | 437 | mz_zip_file file_info; |
31 | 437 | void *fuzz_stream = NULL; |
32 | 437 | void *stream = NULL; |
33 | 437 | void *handle = NULL; |
34 | 437 | int32_t err = MZ_OK; |
35 | 437 | uint16_t value16 = 0; |
36 | 437 | uint8_t value8 = 0; |
37 | 437 | int16_t compress_level = 0; |
38 | 437 | int64_t fuzz_pos = 0; |
39 | 437 | int32_t fuzz_length = 0; |
40 | 437 | uint8_t *fuzz_buf = NULL; |
41 | 437 | const char *password = NULL; |
42 | | |
43 | 437 | fuzz_stream = mz_stream_mem_create(); |
44 | 437 | if (!fuzz_stream) |
45 | 0 | return 1; |
46 | 437 | mz_stream_mem_set_buffer(fuzz_stream, (void *)data, (int32_t)size); |
47 | | |
48 | 437 | memset(&file_info, 0, sizeof(file_info)); |
49 | | |
50 | 437 | file_info.flag = MZ_ZIP_FLAG_UTF8; |
51 | 437 | if ((mz_stream_read_uint8(fuzz_stream, &value8) == MZ_OK) && (value8 < 0x08)) { |
52 | 215 | if (mz_stream_read_uint16(fuzz_stream, &value16) == MZ_OK) |
53 | 209 | file_info.flag = value16; |
54 | 215 | } |
55 | 437 | file_info.compression_method = MZ_COMPRESS_METHOD_DEFLATE; |
56 | 437 | if ((mz_stream_read_uint8(fuzz_stream, &value8) == MZ_OK) && (value8 < 0x08)) { |
57 | 331 | file_info.compression_method = MZ_COMPRESS_METHOD_STORE; |
58 | 331 | } else if ((mz_stream_read_uint8(fuzz_stream, &value8) == MZ_OK) && (value8 < 0x08)) { |
59 | 47 | if (mz_stream_read_uint16(fuzz_stream, &value16) == MZ_OK) |
60 | 43 | file_info.compression_method = value16; |
61 | 47 | } |
62 | | |
63 | 437 | if ((mz_stream_read_uint8(fuzz_stream, &value8) == MZ_OK) && (value8 < 0x08)) { |
64 | 115 | if (mz_stream_read_uint16(fuzz_stream, &value16) == MZ_OK) |
65 | 108 | file_info.zip64 = value16; |
66 | 115 | } |
67 | | |
68 | 437 | file_info.filename = MZ_FUZZ_TEST_FILENAME; |
69 | 437 | file_info.filename_size = (uint16_t)strlen(MZ_FUZZ_TEST_FILENAME); |
70 | | |
71 | 437 | compress_level = MZ_COMPRESS_LEVEL_DEFAULT; |
72 | 437 | if ((mz_stream_read_uint8(fuzz_stream, &value8) == MZ_OK) && (value8 < 0x08)) { |
73 | 86 | if (mz_stream_read_uint16(fuzz_stream, &value16) == MZ_OK) |
74 | 81 | compress_level = value16; |
75 | 86 | } |
76 | | |
77 | 437 | stream = mz_stream_mem_create(); |
78 | 437 | if (!stream) { |
79 | 0 | mz_stream_mem_delete(&fuzz_stream); |
80 | 0 | return 1; |
81 | 0 | } |
82 | | |
83 | 437 | err = mz_stream_mem_open(stream, MZ_FUZZ_TEST_FILENAME, MZ_OPEN_MODE_CREATE | MZ_OPEN_MODE_WRITE); |
84 | 437 | if (err != MZ_OK) { |
85 | 0 | mz_stream_mem_delete(&stream); |
86 | 0 | mz_stream_mem_delete(&fuzz_stream); |
87 | 0 | return 1; |
88 | 0 | } |
89 | | |
90 | 437 | handle = mz_zip_create(); |
91 | 437 | if (!handle) { |
92 | 0 | mz_stream_mem_delete(&stream); |
93 | 0 | mz_stream_mem_delete(&fuzz_stream); |
94 | 0 | return 1; |
95 | 0 | } |
96 | | |
97 | 437 | err = mz_zip_open(handle, stream, MZ_OPEN_MODE_CREATE | MZ_OPEN_MODE_WRITE); |
98 | 437 | if (err == MZ_OK) { |
99 | 437 | password = file_info.flag & MZ_ZIP_FLAG_ENCRYPTED ? MZ_FUZZ_TEST_PWD : NULL; |
100 | 437 | err = mz_zip_entry_write_open(handle, &file_info, compress_level, 0, password); |
101 | 437 | if (err == MZ_OK) { |
102 | 348 | mz_stream_mem_get_buffer_at_current(fuzz_stream, (const void **)&fuzz_buf); |
103 | 348 | fuzz_pos = mz_stream_tell(fuzz_stream); |
104 | 348 | mz_stream_mem_get_buffer_length(fuzz_stream, &fuzz_length); |
105 | | |
106 | 348 | err = mz_zip_entry_write(handle, fuzz_buf, (fuzz_length - (int32_t)fuzz_pos)); |
107 | | |
108 | 348 | mz_zip_entry_close(handle); |
109 | 348 | } |
110 | | |
111 | 437 | mz_zip_close(handle); |
112 | 437 | } |
113 | | |
114 | 437 | mz_zip_delete(&handle); |
115 | 437 | mz_stream_mem_delete(&stream); |
116 | | |
117 | 437 | mz_stream_mem_delete(&fuzz_stream); |
118 | | |
119 | 437 | return 0; |
120 | 437 | } |
121 | | |
122 | | /***************************************************************************/ |
123 | | |
124 | | #ifdef __cplusplus |
125 | | } |
126 | | #endif |