Skip to content

Commit

Permalink
Merge pull request #175 from kuba--/err-code
Browse files Browse the repository at this point in the history
Return code on error
  • Loading branch information
kuba-- authored Mar 13, 2021
2 parents d01ec45 + 252d6c1 commit 54af749
Show file tree
Hide file tree
Showing 8 changed files with 370 additions and 231 deletions.
366 changes: 228 additions & 138 deletions src/zip.c

Large diffs are not rendered by default.

42 changes: 41 additions & 1 deletion src/zip.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,49 @@ typedef long ssize_t; /* byte count or error */
/**
* Default zip compression level.
*/

#define ZIP_DEFAULT_COMPRESSION_LEVEL 6

/**
* Error codes
*/
#define ZIP_ENOINIT -1 // not initialized
#define ZIP_EINVENTNAME -2 // invalid entry name
#define ZIP_ENOENT -3 // entry not found
#define ZIP_EINVMODE -4 // invalid zip mode
#define ZIP_EINVLVL -5 // invalid compression level
#define ZIP_ENOSUP64 -6 // no zip 64 support
#define ZIP_EMEMSET -7 // memset error
#define ZIP_EWRTENT -8 // cannot write data to entry
#define ZIP_ETDEFLINIT -9 // cannot initialize tdefl compressor
#define ZIP_EINVIDX -10 // invalid index
#define ZIP_ENOHDR -11 // header not found
#define ZIP_ETDEFLBUF -12 // cannot flush tdefl buffer
#define ZIP_ECRTHDR -13 // cannot create entry header
#define ZIP_EWRTHDR -14 // cannot write entry header
#define ZIP_EWRTDIR -15 // cannot write to central dir
#define ZIP_EOPNFILE -16 // cannot open file
#define ZIP_EINVENTTYPE -17 // invalid entry type
#define ZIP_EMEMNOALLOC -18 // extracting data using no memory allocation
#define ZIP_ENOFILE -19 // file not found
#define ZIP_ENOPERM -20 // no permission
#define ZIP_EOOMEM -21 // out of memory
#define ZIP_EINVZIPNAME -22 // invalid zip archive name
#define ZIP_EMKDIR -23 // make dir error
#define ZIP_ESYMLINK -24 // symlink error
#define ZIP_ECLSZIP -25 // close archive error
#define ZIP_ECAPSIZE -26 // capacity size too small
#define ZIP_EFSEEK -27 // fseek error
#define ZIP_EFREAD -28 // fread error
#define ZIP_EFWRITE -29 // fwrite error

/**
* Looks up the error message string coresponding to an error number.
* @param errnum error number
* @return error message string coresponding to errnum or NULL if error is not
* found.
*/
extern const char *zip_strerror(int errnum);

/**
* @struct zip_t
*
Expand Down
6 changes: 3 additions & 3 deletions test/test_append.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,23 +47,23 @@ MU_TEST(test_append) {
mu_assert_int_eq(0, zip_entry_open(zip, "test\\empty/"));
mu_assert_int_eq(0, strcmp(zip_entry_name(zip), "test/empty/"));
mu_assert_int_eq(0, zip_entry_size(zip));
mu_check(0 == zip_entry_crc32(zip));
mu_assert_int_eq(0, zip_entry_crc32(zip));
mu_assert_int_eq(total_entries, zip_entry_index(zip));
mu_assert_int_eq(0, zip_entry_close(zip));
++total_entries;

mu_assert_int_eq(0, zip_entry_open(zip, "empty/"));
mu_assert_int_eq(0, strcmp(zip_entry_name(zip), "empty/"));
mu_assert_int_eq(0, zip_entry_size(zip));
mu_check(0 == zip_entry_crc32(zip));
mu_assert_int_eq(0, zip_entry_crc32(zip));
mu_assert_int_eq(total_entries, zip_entry_index(zip));
mu_assert_int_eq(0, zip_entry_close(zip));
++total_entries;

mu_assert_int_eq(0, zip_entry_open(zip, "dotfiles/.test"));
mu_assert_int_eq(0, strcmp(zip_entry_name(zip), "dotfiles/.test"));
mu_assert_int_eq(0, zip_entry_size(zip));
mu_check(0 == zip_entry_crc32(zip));
mu_assert_int_eq(0, zip_entry_crc32(zip));
mu_assert_int_eq(0, zip_entry_write(zip, TESTDATA2, strlen(TESTDATA2)));
mu_assert_int_eq(strlen(TESTDATA2), zip_entry_size(zip));
mu_check(CRC32DATA2 == zip_entry_crc32(zip));
Expand Down
86 changes: 46 additions & 40 deletions test/test_entry.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,22 +89,22 @@ MU_TEST(test_entry_name) {

mu_check(zip_entry_name(zip) == NULL);

mu_check(0 == zip_entry_open(zip, "test\\test-1.txt"));
mu_assert_int_eq(0, zip_entry_open(zip, "test\\test-1.txt"));
mu_check(NULL != zip_entry_name(zip));
mu_check(0 == strcmp(zip_entry_name(zip), "test/test-1.txt"));
mu_assert_int_eq(0, strcmp(zip_entry_name(zip), "test/test-1.txt"));
mu_assert_int_eq(strlen(TESTDATA1), zip_entry_size(zip));
mu_check(CRC32DATA1 == zip_entry_crc32(zip));
mu_assert_int_eq(0, zip_entry_index(zip));

mu_check(0 == zip_entry_close(zip));
mu_assert_int_eq(0, zip_entry_close(zip));

mu_check(0 == zip_entry_open(zip, "test/test-2.txt"));
mu_assert_int_eq(0, zip_entry_open(zip, "test/test-2.txt"));
mu_check(NULL != zip_entry_name(zip));
mu_check(0 == strcmp(zip_entry_name(zip), "test/test-2.txt"));
mu_assert_int_eq(0, strcmp(zip_entry_name(zip), "test/test-2.txt"));
mu_assert_int_eq(strlen(TESTDATA2), zip_entry_size(zip));
mu_check(CRC32DATA2 == zip_entry_crc32(zip));
mu_assert_int_eq(1, zip_entry_index(zip));
mu_check(0 == zip_entry_close(zip));
mu_assert_int_eq(0, zip_entry_close(zip));

zip_close(zip);
}
Expand All @@ -113,19 +113,19 @@ MU_TEST(test_entry_index) {
struct zip_t *zip = zip_open(ZIPNAME, 0, 'r');
mu_check(zip != NULL);

mu_check(0 == zip_entry_open(zip, "test\\test-1.txt"));
mu_assert_int_eq(0, zip_entry_open(zip, "test\\test-1.txt"));
mu_assert_int_eq(0, zip_entry_index(zip));
mu_check(0 == strcmp(zip_entry_name(zip), "test/test-1.txt"));
mu_assert_int_eq(0, strcmp(zip_entry_name(zip), "test/test-1.txt"));
mu_assert_int_eq(strlen(TESTDATA1), zip_entry_size(zip));
mu_check(CRC32DATA1 == zip_entry_crc32(zip));
mu_check(0 == zip_entry_close(zip));
mu_assert_int_eq(0, zip_entry_close(zip));

mu_check(0 == zip_entry_open(zip, "test/test-2.txt"));
mu_assert_int_eq(0, zip_entry_open(zip, "test/test-2.txt"));
mu_assert_int_eq(1, zip_entry_index(zip));
mu_check(0 == strcmp(zip_entry_name(zip), "test/test-2.txt"));
mu_assert_int_eq(0, strcmp(zip_entry_name(zip), "test/test-2.txt"));
mu_assert_int_eq(strlen(TESTDATA2), zip_entry_size(zip));
mu_check(CRC32DATA2 == zip_entry_crc32(zip));
mu_check(0 == zip_entry_close(zip));
mu_assert_int_eq(0, zip_entry_close(zip));

zip_close(zip);
}
Expand All @@ -134,19 +134,19 @@ MU_TEST(test_entry_openbyindex) {
struct zip_t *zip = zip_open(ZIPNAME, 0, 'r');
mu_check(zip != NULL);

mu_check(0 == zip_entry_openbyindex(zip, 1));
mu_assert_int_eq(0, zip_entry_openbyindex(zip, 1));
mu_assert_int_eq(1, zip_entry_index(zip));
mu_assert_int_eq(strlen(TESTDATA2), zip_entry_size(zip));
mu_check(CRC32DATA2 == zip_entry_crc32(zip));
mu_check(0 == strcmp(zip_entry_name(zip), "test/test-2.txt"));
mu_check(0 == zip_entry_close(zip));
mu_assert_int_eq(0, strcmp(zip_entry_name(zip), "test/test-2.txt"));
mu_assert_int_eq(0, zip_entry_close(zip));

mu_check(0 == zip_entry_openbyindex(zip, 0));
mu_assert_int_eq(0, zip_entry_openbyindex(zip, 0));
mu_assert_int_eq(0, zip_entry_index(zip));
mu_assert_int_eq(strlen(TESTDATA1), zip_entry_size(zip));
mu_check(CRC32DATA1 == zip_entry_crc32(zip));
mu_check(0 == strcmp(zip_entry_name(zip), "test/test-1.txt"));
mu_check(0 == zip_entry_close(zip));
mu_assert_int_eq(0, strcmp(zip_entry_name(zip), "test/test-1.txt"));
mu_assert_int_eq(0, zip_entry_close(zip));

zip_close(zip);
}
Expand All @@ -161,23 +161,23 @@ MU_TEST(test_entry_read) {
zip_stream_open(NULL, 0, ZIP_DEFAULT_COMPRESSION_LEVEL, 'w');
mu_check(zip != NULL);

mu_check(0 == zip_entry_open(zip, "test/test-1.txt"));
mu_check(0 == zip_entry_write(zip, TESTDATA1, strlen(TESTDATA1)));
mu_check(0 == zip_entry_close(zip));
mu_assert_int_eq(0, zip_entry_open(zip, "test/test-1.txt"));
mu_assert_int_eq(0, zip_entry_write(zip, TESTDATA1, strlen(TESTDATA1)));
mu_assert_int_eq(0, zip_entry_close(zip));

ssize_t n = zip_stream_copy(zip, (void **)&bufencode1, NULL);
zip_stream_copy(zip, (void **)&bufencode2, &n);
mu_check(0 == strncmp(bufencode1, bufencode2, (size_t)n));
mu_assert_int_eq(0, strncmp(bufencode1, bufencode2, (size_t)n));

zip_stream_close(zip);

struct zip_t *zipstream = zip_stream_open(bufencode1, n, 0, 'r');
mu_check(zipstream != NULL);

mu_check(0 == zip_entry_open(zipstream, "test/test-1.txt"));
mu_assert_int_eq(0, zip_entry_open(zipstream, "test/test-1.txt"));
bufsize = zip_entry_read(zipstream, (void **)&buf, NULL);
mu_check(0 == strncmp(buf, TESTDATA1, (size_t)bufsize));
mu_check(0 == zip_entry_close(zipstream));
mu_assert_int_eq(0, strncmp(buf, TESTDATA1, (size_t)bufsize));
mu_assert_int_eq(0, zip_entry_close(zipstream));

zip_stream_close(zipstream);

Expand All @@ -192,13 +192,13 @@ MU_TEST(test_list_entries) {

int i = 0, n = zip_entries_total(zip);
for (; i < n; ++i) {
mu_check(0 == zip_entry_openbyindex(zip, i));
mu_assert_int_eq(0, zip_entry_openbyindex(zip, i));
fprintf(stdout, "[%d]: %s", i, zip_entry_name(zip));
if (zip_entry_isdir(zip)) {
fprintf(stdout, " (DIR)");
}
fprintf(stdout, "\n");
mu_check(0 == zip_entry_close(zip));
mu_assert_int_eq(0, zip_entry_close(zip));
}

zip_close(zip);
Expand All @@ -218,32 +218,38 @@ MU_TEST(test_entries_delete) {
zip = zip_open(ZIPNAME, 0, 'r');
mu_check(zip != NULL);

mu_check(0 > zip_entry_open(zip, "delete.me"));
mu_check(0 == zip_entry_close(zip));
mu_assert_int_eq(ZIP_ENOENT, zip_entry_open(zip, "delete.me"));
mu_assert_int_eq(0, zip_entry_close(zip));
fprintf(stdout, "delete.me: %s\n", zip_strerror(ZIP_ENOENT));

mu_check(0 > zip_entry_open(zip, "_"));
mu_check(0 == zip_entry_close(zip));
mu_assert_int_eq(ZIP_ENOENT, zip_entry_open(zip, "_"));
mu_assert_int_eq(0, zip_entry_close(zip));
fprintf(stdout, "_: %s\n", zip_strerror(ZIP_ENOENT));

mu_check(0 > zip_entry_open(zip, "delete/file.1"));
mu_check(0 == zip_entry_close(zip));
mu_assert_int_eq(ZIP_ENOENT, zip_entry_open(zip, "delete/file.1"));
mu_assert_int_eq(0, zip_entry_close(zip));
fprintf(stdout, "delete/file.1: %s\n", zip_strerror(ZIP_ENOENT));

mu_check(0 > zip_entry_open(zip, "deleteme/file.3"));
mu_check(0 == zip_entry_close(zip));
mu_check(0 > zip_entry_open(zip, "delete/file.2"));
mu_check(0 == zip_entry_close(zip));
mu_assert_int_eq(ZIP_ENOENT, zip_entry_open(zip, "deleteme/file.3"));
mu_assert_int_eq(0, zip_entry_close(zip));
fprintf(stdout, "delete/file.3: %s\n", zip_strerror(ZIP_ENOENT));

mu_assert_int_eq(ZIP_ENOENT, zip_entry_open(zip, "delete/file.2"));
mu_assert_int_eq(0, zip_entry_close(zip));
fprintf(stdout, "delete/file.2: %s\n", zip_strerror(ZIP_ENOENT));

mu_assert_int_eq(total_entries - 5, zip_entries_total(zip));

mu_check(0 == zip_entry_open(zip, "delete/file.4"));
mu_assert_int_eq(0, zip_entry_open(zip, "delete/file.4"));

size_t buftmp = 0;
char *buf = NULL;
ssize_t bufsize = zip_entry_read(zip, (void **)&buf, &buftmp);

mu_assert_int_eq(bufsize, strlen(TESTDATA2));
mu_assert_int_eq((size_t)bufsize, buftmp);
mu_check(0 == strncmp(buf, TESTDATA2, bufsize));
mu_check(0 == zip_entry_close(zip));
mu_assert_int_eq(0, strncmp(buf, TESTDATA2, bufsize));
mu_assert_int_eq(0, zip_entry_close(zip));

free(buf);
buf = NULL;
Expand Down
25 changes: 14 additions & 11 deletions test/test_extract.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,23 +77,23 @@ MU_TEST(test_extract) {

memset((void *)&buf, 0, sizeof(struct buffer_t));

mu_check(0 == zip_entry_open(zip, "test/test-1.txt"));
mu_check(0 == zip_entry_extract(zip, on_extract, &buf));
mu_assert_int_eq(0, zip_entry_open(zip, "test/test-1.txt"));
mu_assert_int_eq(0, zip_entry_extract(zip, on_extract, &buf));
mu_assert_int_eq(strlen(TESTDATA1), buf.size);
mu_check(0 == strncmp(buf.data, TESTDATA1, buf.size));
mu_check(0 == zip_entry_close(zip));
mu_assert_int_eq(0, strncmp(buf.data, TESTDATA1, buf.size));
mu_assert_int_eq(0, zip_entry_close(zip));

free(buf.data);
buf.data = NULL;
buf.size = 0;

memset((void *)&buf, 0, sizeof(struct buffer_t));

mu_check(0 == zip_entry_open(zip, "dotfiles/.test"));
mu_check(0 == zip_entry_extract(zip, on_extract, &buf));
mu_assert_int_eq(0, zip_entry_open(zip, "dotfiles/.test"));
mu_assert_int_eq(0, zip_entry_extract(zip, on_extract, &buf));
mu_assert_int_eq(strlen(TESTDATA2), buf.size);
mu_check(0 == strncmp(buf.data, TESTDATA2, buf.size));
mu_check(0 == zip_entry_close(zip));
mu_assert_int_eq(0, strncmp(buf.data, TESTDATA2, buf.size));
mu_assert_int_eq(0, zip_entry_close(zip));

free(buf.data);
buf.data = NULL;
Expand All @@ -103,9 +103,12 @@ MU_TEST(test_extract) {
}

MU_TEST(test_extract_stream) {
mu_check(0 > zip_extract("non_existing_directory/non_existing_archive.zip",
".", NULL, NULL));
mu_check(0 > zip_stream_extract("", 0, ".", NULL, NULL));
mu_assert_int_eq(
ZIP_ENOINIT,
zip_extract("non_existing_directory/non_existing_archive.zip", ".", NULL,
NULL));
mu_assert_int_eq(ZIP_ENOINIT, zip_stream_extract("", 0, ".", NULL, NULL));
fprintf(stdout, "zip_stream_extract: %s\n", zip_strerror(ZIP_ENOINIT));

FILE *fp = NULL;
#if defined(_MSC_VER)
Expand Down
36 changes: 18 additions & 18 deletions test/test_permissions.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,12 @@ MU_TEST(test_exe_permissions) {
fclose(f);
chmod(XFILE, XMODE);

mu_check(0 == zip_create(ZIPNAME, filenames, 1));
mu_assert_int_eq(0, zip_create(ZIPNAME, filenames, 1));
remove(XFILE);

mu_check(0 == zip_extract(ZIPNAME, ".", NULL, NULL));
mu_assert_int_eq(0, zip_extract(ZIPNAME, ".", NULL, NULL));

mu_check(0 == MZ_FILE_STAT(XFILE, &file_stats));
mu_assert_int_eq(0, MZ_FILE_STAT(XFILE, &file_stats));
mu_assert_int_eq(XMODE, file_stats.st_mode);
}

Expand All @@ -73,8 +73,8 @@ MU_TEST(test_read_permissions) {
mu_assert_int_eq(0, zip_create(ZIPNAME, filenames, 1));
remove(RFILE);

mu_check(0 == zip_extract(ZIPNAME, ".", NULL, NULL));
mu_check(0 == MZ_FILE_STAT(RFILE, &file_stats));
mu_assert_int_eq(0, zip_extract(ZIPNAME, ".", NULL, NULL));
mu_assert_int_eq(0, MZ_FILE_STAT(RFILE, &file_stats));
mu_assert_int_eq(RMODE, file_stats.st_mode);

// chmod from 444 to 666 to be able delete the file on windows
Expand All @@ -89,11 +89,11 @@ MU_TEST(test_write_permissions) {
fclose(f);
chmod(WFILE, WMODE);

mu_check(0 == zip_create(ZIPNAME, filenames, 1));
mu_assert_int_eq(0, zip_create(ZIPNAME, filenames, 1));
remove(WFILE);

mu_check(0 == zip_extract(ZIPNAME, ".", NULL, NULL));
mu_check(0 == MZ_FILE_STAT(WFILE, &file_stats));
mu_assert_int_eq(0, zip_extract(ZIPNAME, ".", NULL, NULL));
mu_assert_int_eq(0, MZ_FILE_STAT(WFILE, &file_stats));
mu_assert_int_eq(WMODE, file_stats.st_mode);
}

Expand All @@ -106,15 +106,15 @@ MU_TEST(test_unix_permissions) {
struct zip_t *zip = zip_open(ZIPNAME, ZIP_DEFAULT_COMPRESSION_LEVEL, 'w');
mu_check(zip != NULL);

mu_check(0 == zip_entry_open(zip, RFILE));
mu_check(0 == zip_entry_write(zip, TESTDATA1, strlen(TESTDATA1)));
mu_check(0 == zip_entry_close(zip));
mu_assert_int_eq(0, zip_entry_open(zip, RFILE));
mu_assert_int_eq(0, zip_entry_write(zip, TESTDATA1, strlen(TESTDATA1)));
mu_assert_int_eq(0, zip_entry_close(zip));

zip_close(zip);

mu_assert_int_eq(0, zip_extract(ZIPNAME, ".", NULL, NULL));

mu_check(0 == MZ_FILE_STAT(RFILE, &file_stats));
mu_assert_int_eq(0, MZ_FILE_STAT(RFILE, &file_stats));

mu_assert_int_eq(UNIXMODE, file_stats.st_mode);
}
Expand All @@ -134,25 +134,25 @@ MU_TEST(test_mtime) {
mu_fail("Cannot open filename\n");
}
fwrite(TESTDATA1, sizeof(char), strlen(TESTDATA1), stream);
mu_check(0 == fclose(stream));
mu_assert_int_eq(0, fclose(stream));

memset(&file_stat1, 0, sizeof(file_stat1));
memset(&file_stat2, 0, sizeof(file_stat2));

zip = zip_open(ZIPNAME, ZIP_DEFAULT_COMPRESSION_LEVEL, 'w');
mu_check(zip != NULL);

mu_check(0 == zip_entry_open(zip, filename));
mu_check(0 == zip_entry_fwrite(zip, filename));
mu_check(0 == zip_entry_close(zip));
mu_assert_int_eq(0, zip_entry_open(zip, filename));
mu_assert_int_eq(0, zip_entry_fwrite(zip, filename));
mu_assert_int_eq(0, zip_entry_close(zip));

zip_close(zip);

mu_check(0 == MZ_FILE_STAT(filename, &file_stat1));
mu_assert_int_eq(0, MZ_FILE_STAT(filename, &file_stat1));
remove(filename);

mu_assert_int_eq(0, zip_extract(ZIPNAME, ".", NULL, NULL));
mu_check(0 == MZ_FILE_STAT(filename, &file_stat2));
mu_assert_int_eq(0, MZ_FILE_STAT(filename, &file_stat2));
remove(filename);

fprintf(stdout, "file_stat1.st_mtime: %lu\n", file_stat1.st_mtime);
Expand Down
Loading

0 comments on commit 54af749

Please sign in to comment.