-
Notifications
You must be signed in to change notification settings - Fork 336
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #325 from tyler92/add-in-place-fuzzer
Add fuzzer for mz_zip_add_mem_to_archive_file_in_place function
- Loading branch information
Showing
2 changed files
with
91 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
#include <stdio.h> | ||
#include <limits.h> | ||
#include "miniz.h" | ||
|
||
static const mz_uint files_count = 5; | ||
static const mz_uint max_file_size = 1024 * 1024; | ||
static const char *zip_file_name = "/tmp/miniz-fuzzer-test.zip"; | ||
|
||
/* Read 32-bit integer from the fuzzer input with range [0, max] */ | ||
static mz_uint read_uint32(const mz_uint8 **data, size_t *size, mz_uint max) | ||
{ | ||
mz_uint value = 0; | ||
|
||
if (*size >= sizeof(mz_uint)) | ||
{ | ||
memcpy(&value, *data, sizeof(mz_uint)); | ||
*data += sizeof(mz_uint); | ||
*size -= sizeof(mz_uint); | ||
value = MZ_MIN(max == UINT_MAX ? value : value % (max + 1), *size); | ||
} | ||
|
||
return value; | ||
} | ||
|
||
/* Read random-length null terminated string from the fuzzer input */ | ||
static mz_bool read_string(const mz_uint8 **data, size_t *size, char *destination, mz_uint max_len) | ||
{ | ||
mz_uint filename_len = read_uint32(data, size, max_len - 1); | ||
memcpy(destination, *data, filename_len); | ||
destination[filename_len] = 0; | ||
*data += filename_len; | ||
*size -= filename_len; | ||
return filename_len > 0; | ||
} | ||
|
||
/* Get random-length buffer from the fuzzer input */ | ||
static mz_bool read_buffer(const mz_uint8 **data, size_t *size, const mz_uint8 **destination, mz_uint *len) | ||
{ | ||
*len = read_uint32(data, size, max_file_size); | ||
*destination = *data; | ||
*data += *len; | ||
*size -= *len; | ||
return *len > 0; | ||
} | ||
|
||
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) | ||
{ | ||
mz_uint i; | ||
char archive_file_name[FILENAME_MAX]; | ||
const mz_uint8 *file_data; | ||
mz_uint file_length, flags; | ||
size_t extracted_size; | ||
mz_uint8 *extracted_data; | ||
const char *comment = mz_version(); | ||
|
||
/* Remove the temporary file for better reproducibility */ | ||
remove(zip_file_name); | ||
|
||
for (i = 0; i < files_count; ++i) | ||
{ | ||
/* Fill archive file name */ | ||
if (!read_string(&data, &size, archive_file_name, sizeof(archive_file_name))) | ||
{ | ||
break; | ||
} | ||
|
||
/* Prepare file's content */ | ||
if (!read_buffer(&data, &size, &file_data, &file_length)) | ||
{ | ||
break; | ||
} | ||
|
||
/* Prepare flags for adding file */ | ||
flags = read_uint32(&data, &size, UINT_MAX); | ||
|
||
mz_zip_add_mem_to_archive_file_in_place(zip_file_name, archive_file_name, file_data, file_length, comment, | ||
(mz_uint16)strlen(comment), flags); | ||
|
||
/* Prepare flags for extracting file */ | ||
flags = read_uint32(&data, &size, UINT_MAX); | ||
extracted_data = mz_zip_extract_archive_file_to_heap(zip_file_name, archive_file_name, &extracted_size, flags); | ||
free(extracted_data); | ||
} | ||
|
||
remove(zip_file_name); | ||
return 0; | ||
} |