#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <zip.h>

/**
This fuzzing target takes input data, creates a ZIP archive, load
it to a buffer, adds a file to it with traditional PKWARE
encryption and a specified password, and then closes and removes
the archive.

The purpose of this fuzzer is to test security of ZIP archive
handling and encryption in the libzip by subjecting it to various
inputs, including potentially malicious or malformed data of
different file types.
**/

#ifdef __cplusplus
extern "C"
#endif
int
LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
    const char *path = "test_pkware.zip";
    const char *password = "password";
    const char *file = "filename";
    int error = 0;
    struct zip *archive;

    (void)remove(path);
    if ((archive = zip_open(path, ZIP_CREATE, &error)) == NULL) {
        return -1;
    }

    struct zip_source *source = zip_source_buffer(archive, data, size, 0);
    if (source == NULL) {
        fprintf(stderr, "failed to create source buffer. %s\n", zip_strerror(archive));
        zip_discard(archive);
        return -1;
    }

    int index = (int)zip_file_add(archive, file, source, ZIP_FL_OVERWRITE);
    if (index < 0) {
        fprintf(stderr, "failed to add file to archive: %s\n", zip_strerror(archive));
        zip_discard(archive);
        return -1;
    }
    if (zip_file_set_encryption(archive, index, ZIP_EM_TRAD_PKWARE, password) < 0) {
        fprintf(stderr, "failed to set file encryption: %s\n", zip_strerror(archive));
        zip_discard(archive);
        return -1;
    }
    if (zip_close(archive) < 0) {
        fprintf(stderr, "error closing archive: %s\n", zip_strerror(archive));
        zip_discard(archive);
        return -1;
    }
    (void)remove(path);

    return 0;
}
