summaryrefslogtreecommitdiff
path: root/libs/zip/test/test_read.c
diff options
context:
space:
mode:
authorAldrik Ramaekers <aldrikboy@gmail.com>2025-08-23 11:18:44 +0200
committerAldrik Ramaekers <aldrikboy@gmail.com>2025-08-23 11:18:44 +0200
commit359422c97cce93bbb27051f9df3efb45bd0b9052 (patch)
tree2e352bb852a25390d40d45e199f835d218ad497f /libs/zip/test/test_read.c
parent8ea59863c5d13e68e080cf7612047ea4c655292c (diff)
settings file writing
Diffstat (limited to 'libs/zip/test/test_read.c')
-rw-r--r--libs/zip/test/test_read.c198
1 files changed, 198 insertions, 0 deletions
diff --git a/libs/zip/test/test_read.c b/libs/zip/test/test_read.c
new file mode 100644
index 0000000..4eb8b0e
--- /dev/null
+++ b/libs/zip/test/test_read.c
@@ -0,0 +1,198 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <zip.h>
+
+#include "minunit.h"
+
+#if defined(_WIN32) || defined(_WIN64)
+#include <io.h>
+
+#define MKTEMP _mktemp
+#else
+#define MKTEMP mkstemp
+#endif
+
+static char ZIPNAME[L_tmpnam + 1] = {0};
+
+#define CRC32DATA1 2220805626
+#define TESTDATA1 "Some test data 1...\0"
+
+#define TESTDATA2 "Some test data 2...\0"
+#define CRC32DATA2 2532008468
+
+void test_setup(void) {
+ strncpy(ZIPNAME, "z-XXXXXX\0", L_tmpnam);
+ MKTEMP(ZIPNAME);
+
+ struct zip_t *zip = zip_open(ZIPNAME, ZIP_DEFAULT_COMPRESSION_LEVEL, 'w');
+
+ zip_entry_open(zip, "test/test-1.txt");
+ zip_entry_write(zip, TESTDATA1, strlen(TESTDATA1));
+ zip_entry_close(zip);
+
+ zip_entry_open(zip, "test\\test-2.txt");
+ zip_entry_write(zip, TESTDATA2, strlen(TESTDATA2));
+ zip_entry_close(zip);
+
+ zip_entry_open(zip, "test\\empty/");
+ zip_entry_close(zip);
+
+ zip_entry_open(zip, "empty/");
+ zip_entry_close(zip);
+
+ zip_entry_open(zip, "dotfiles/.test");
+ zip_entry_write(zip, TESTDATA2, strlen(TESTDATA2));
+ zip_entry_close(zip);
+
+ zip_close(zip);
+}
+
+void test_teardown(void) { remove(ZIPNAME); }
+
+MU_TEST(test_read) {
+ char *buf = NULL;
+ ssize_t bufsize;
+ size_t buftmp;
+
+ struct zip_t *zip = zip_open(ZIPNAME, 0, 'r');
+ mu_check(zip != NULL);
+ mu_assert_int_eq(1, zip_is64(zip));
+
+ mu_assert_int_eq(0, zip_entry_open(zip, "test/test-1.txt"));
+ mu_assert_int_eq(strlen(TESTDATA1), zip_entry_size(zip));
+ mu_check(CRC32DATA1 == zip_entry_crc32(zip));
+ bufsize = zip_entry_read(zip, (void **)&buf, &buftmp);
+ mu_assert_int_eq(strlen(TESTDATA1), bufsize);
+ mu_assert_int_eq((size_t)bufsize, buftmp);
+ mu_assert_int_eq(0, strncmp(buf, TESTDATA1, bufsize));
+ mu_assert_int_eq(0, zip_entry_close(zip));
+ free(buf);
+ buf = NULL;
+
+ mu_assert_int_eq(0, zip_entry_open(zip, "test/test-2.txt"));
+ mu_assert_int_eq(strlen(TESTDATA2), zip_entry_size(zip));
+ mu_check(CRC32DATA2 == zip_entry_crc32(zip));
+ bufsize = zip_entry_read(zip, (void **)&buf, NULL);
+ mu_assert_int_eq(strlen(TESTDATA2), (size_t)bufsize);
+ mu_assert_int_eq(0, strncmp(buf, TESTDATA2, (size_t)bufsize));
+ mu_assert_int_eq(0, zip_entry_close(zip));
+ free(buf);
+ buf = NULL;
+
+ 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_assert_int_eq(0, zip_entry_crc32(zip));
+ mu_assert_int_eq(0, zip_entry_close(zip));
+
+ zip_close(zip);
+}
+
+MU_TEST(test_noallocread) {
+ ssize_t bufsize;
+ size_t buftmp = strlen(TESTDATA2);
+ char *buf = calloc(buftmp, sizeof(char));
+
+ struct zip_t *zip = zip_open(ZIPNAME, 0, 'r');
+ mu_check(zip != NULL);
+ mu_assert_int_eq(1, zip_is64(zip));
+
+ mu_assert_int_eq(0, zip_entry_open(zip, "test/test-2.txt"));
+ bufsize = zip_entry_noallocread(zip, (void *)buf, buftmp);
+ mu_assert_int_eq(buftmp, (size_t)bufsize);
+ mu_assert_int_eq(0, strncmp(buf, TESTDATA2, buftmp));
+ mu_assert_int_eq(0, zip_entry_close(zip));
+ free(buf);
+ buf = NULL;
+
+ buftmp = strlen(TESTDATA1);
+ buf = calloc(buftmp, sizeof(char));
+ mu_assert_int_eq(0, zip_entry_open(zip, "test/test-1.txt"));
+ bufsize = zip_entry_noallocread(zip, (void *)buf, buftmp);
+ mu_assert_int_eq(buftmp, (size_t)bufsize);
+ mu_assert_int_eq(0, strncmp(buf, TESTDATA1, buftmp));
+ mu_assert_int_eq(0, zip_entry_close(zip));
+ free(buf);
+ buf = NULL;
+
+ buftmp = strlen(TESTDATA2);
+ buf = calloc(buftmp, sizeof(char));
+ mu_assert_int_eq(0, zip_entry_open(zip, "dotfiles/.test"));
+ bufsize = zip_entry_noallocread(zip, (void *)buf, buftmp);
+ mu_assert_int_eq(buftmp, (size_t)bufsize);
+ mu_assert_int_eq(0, strncmp(buf, TESTDATA2, buftmp));
+ mu_assert_int_eq(0, zip_entry_close(zip));
+ free(buf);
+ buf = NULL;
+
+ zip_close(zip);
+}
+
+MU_TEST(test_noallocreadwithoffset) {
+ size_t expected_size = strlen(TESTDATA2);
+ char *expected_data = calloc(expected_size, sizeof(char));
+
+ struct zip_t *zip = zip_open(ZIPNAME, 0, 'r');
+ mu_check(zip != NULL);
+ mu_assert_int_eq(1, zip_is64(zip));
+
+ mu_assert_int_eq(0, zip_entry_open(zip, "test/test-2.txt"));
+ {
+ zip_entry_noallocread(zip, (void *)expected_data, expected_size);
+
+ // Read the file in different chunk sizes
+ for (size_t i = 1; i <= expected_size; ++i) {
+ size_t buflen = i;
+ char *tmpbuf = calloc(buflen, sizeof(char));
+
+ for (size_t j = 0; j < expected_size; ++j) {
+ // we test starting from different offsets, to make sure we hit the
+ // "unaligned" code path
+ size_t offset = j;
+ while (offset < expected_size) {
+
+ ssize_t nread =
+ zip_entry_noallocreadwithoffset(zip, offset, buflen, tmpbuf);
+
+ mu_assert(nread <= buflen, "too many bytes read");
+ mu_assert(0u != nread, "no bytes read");
+
+ // check the data
+ for (ssize_t j = 0; j < nread; ++j) {
+ mu_assert_int_eq(expected_data[offset + j], tmpbuf[j]);
+ }
+
+ offset += nread;
+ }
+ }
+ free(tmpbuf);
+ tmpbuf = NULL;
+ }
+ }
+ mu_assert_int_eq(0, zip_entry_close(zip));
+
+ free(expected_data);
+ expected_data = NULL;
+
+ zip_close(zip);
+}
+
+MU_TEST_SUITE(test_read_suite) {
+ MU_SUITE_CONFIGURE(&test_setup, &test_teardown);
+
+ MU_RUN_TEST(test_read);
+ MU_RUN_TEST(test_noallocread);
+ MU_RUN_TEST(test_noallocreadwithoffset);
+}
+
+#define UNUSED(x) (void)x
+
+int main(int argc, char *argv[]) {
+ UNUSED(argc);
+ UNUSED(argv);
+
+ MU_RUN_SUITE(test_read_suite);
+ MU_REPORT();
+ return MU_EXIT_CODE;
+}