Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add fuzzer for mz_zip_add_mem_to_archive_file_in_place function #325

Merged
merged 1 commit into from
Nov 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@ if(BUILD_FUZZERS)
set(SMALL_FUZZER_SRC_LIST "${FUZZ_MAIN_SRC}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/small_fuzzer.c")
set(LARGE_FUZZER_SRC_LIST "${FUZZ_MAIN_SRC}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/large_fuzzer.c")
set(ZIP_FUZZER_SRC_LIST "${FUZZ_MAIN_SRC}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/zip_fuzzer.c")
set(ADD_IN_PLACE_FUZZER_SRC_LIST "${FUZZ_MAIN_SRC}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/add_in_place_fuzzer.c")

add_executable(checksum_fuzzer ${CHECKSUM_FUZZER_SRC_LIST})
target_link_libraries(checksum_fuzzer miniz)
Expand All @@ -302,6 +303,9 @@ if(BUILD_FUZZERS)

add_executable(zip_fuzzer ${ZIP_FUZZER_SRC_LIST})
target_link_libraries(zip_fuzzer miniz)

add_executable(add_in_place_fuzzer ${ADD_IN_PLACE_FUZZER_SRC_LIST})
target_link_libraries(add_in_place_fuzzer miniz)
endif()

if(BUILD_TESTS)
Expand Down
87 changes: 87 additions & 0 deletions tests/add_in_place_fuzzer.c
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;
}
Loading