1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <memory.h>
6 #include <stddef.h>
7 #include <stdint.h>
8 #include <stdlib.h>
9
10 #include <fuzzer/FuzzedDataProvider.h>
11
12 #include <vector>
13
14 #include "base/scoped_generic.h"
15 #include "third_party/minizip/src/mz.h"
16 #include "third_party/minizip/src/mz_strm_mem.h"
17 #include "third_party/minizip/src/mz_zip.h"
18
19 const char kTestFileName[] = "test.zip";
20
21 namespace {
22
23 struct MzTraitsBase {
InvalidValue__anon8956152c0111::MzTraitsBase24 static void* InvalidValue() { return nullptr; }
25 };
26
27 struct MzStreamMemTraits : public MzTraitsBase {
Free__anon8956152c0111::MzStreamMemTraits28 static void Free(void* stream) { mz_stream_mem_delete(&stream); }
29 };
30 typedef base::ScopedGeneric<void*, MzStreamMemTraits> ScopedMzStreamMem;
31
32 struct MzZipTraits : public MzTraitsBase {
Free__anon8956152c0111::MzZipTraits33 static void Free(void* stream) {
34 mz_zip_close(stream);
35 mz_zip_delete(&stream);
36 }
37 };
38 typedef base::ScopedGeneric<void*, MzZipTraits> ScopedMzZip;
39
40 } // namespace
41
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)42 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
43 FuzzedDataProvider data_provider(data, size);
44
45 mz_zip_file file_info = {};
46 file_info.flag = MZ_ZIP_FLAG_UTF8;
47 if (data_provider.ConsumeIntegral<uint8_t>() < 0x08) {
48 file_info.flag = data_provider.ConsumeIntegral<uint16_t>();
49 }
50 file_info.compression_method = MZ_COMPRESS_METHOD_DEFLATE;
51 if (data_provider.ConsumeIntegral<uint8_t>() < 0x08) {
52 file_info.compression_method = MZ_COMPRESS_METHOD_STORE;
53 } else if (data_provider.ConsumeIntegral<uint8_t>() < 0x08) {
54 file_info.compression_method = data_provider.ConsumeIntegral<uint16_t>();
55 }
56 if (data_provider.ConsumeIntegral<uint8_t>() < 0x08) {
57 file_info.zip64 = data_provider.ConsumeIntegral<uint16_t>();
58 }
59 file_info.filename = kTestFileName;
60 file_info.filename_size = sizeof(kTestFileName);
61
62 int16_t compress_level = MZ_COMPRESS_LEVEL_DEFAULT;
63 if (data_provider.ConsumeIntegral<uint8_t>() < 0x08) {
64 compress_level =
65 static_cast<int16_t>(data_provider.ConsumeIntegral<uint16_t>());
66 }
67
68 ScopedMzStreamMem out_stream(mz_stream_mem_create(nullptr));
69
70 ScopedMzZip zip_file(mz_zip_create(nullptr));
71 int result = mz_zip_open(zip_file.get(), out_stream.get(),
72 MZ_OPEN_MODE_CREATE | MZ_OPEN_MODE_WRITE);
73 if (result != MZ_OK) {
74 return 0;
75 }
76
77 result = mz_zip_entry_write_open(zip_file.get(), &file_info, compress_level,
78 0, nullptr);
79 if (result != MZ_OK) {
80 return 0;
81 }
82
83 std::vector<uint8_t> remaining_data =
84 data_provider.ConsumeRemainingBytes<uint8_t>();
85 result = mz_zip_entry_write(zip_file.get(), remaining_data.data(),
86 remaining_data.size());
87 if (result != MZ_OK) {
88 return 0;
89 }
90
91 result = mz_zip_entry_close(zip_file.get());
92 if (result != MZ_OK) {
93 return 0;
94 }
95
96 result = mz_zip_close(zip_file.get());
97 if (result != MZ_OK) {
98 return 0;
99 }
100
101 return 0;
102 }
103