From fe757798e81a678338079d7832454ebe0b4ad2d5 Mon Sep 17 00:00:00 2001 From: Guido Draheim Date: Sun, 23 Apr 2017 21:43:33 +0200 Subject: [PATCH] fixed zzipcat-mem by changing strdup_name to return emptry string on missing name on disk --- bins/unzzipcat-mem.c | 1 + test/zziptests.py | 20 +++++++--------- zzip/memdisk.c | 25 +++++++++++++++++-- zzip/mmapped.c | 57 +++++++++++++++++++++++++++++++++----------- 4 files changed, 75 insertions(+), 28 deletions(-) diff --git a/bins/unzzipcat-mem.c b/bins/unzzipcat-mem.c index 7474854..39829bc 100644 --- a/bins/unzzipcat-mem.c +++ b/bins/unzzipcat-mem.c @@ -88,6 +88,7 @@ main (int argc, char ** argv) if (argc == 2) { /* print directory list */ ZZIP_MEM_ENTRY* entry = zzip_mem_disk_findfirst(disk); + fprintf(stderr, "..%p\n", entry); for (; entry ; entry = zzip_mem_disk_findnext(disk, entry)) { char* name = zzip_mem_entry_to_name (entry); diff --git a/test/zziptests.py b/test/zziptests.py index 5d8f288..01d16e6 100644 --- a/test/zziptests.py +++ b/test/zziptests.py @@ -562,12 +562,11 @@ class ZZipTest(unittest.TestCase): getfile = "README" logfile = "test1.readme.mmapped.txt" exe = self.bins("unzzipcat-mem") - run = shell("{exe} {getfile} | tee {logfile}".format(**locals())) + run = shell("{exe} {zipfile} {getfile} | tee {logfile}".format(**locals())) self.assertGreater(os.path.getsize(logfile), 10) self.assertEqual(run.output.split("\n"), self.readme().split("\n")) - getfile = "test1/file.1" + getfile = "file.1" run = shell("{exe} {zipfile} {getfile} | tee {logfile}".format(**locals())) - run = shell("{exe} {getfile}".format(**locals())) self.assertEqual("file-1\n", run.output) def test_412_zzcat_test2_zip(self): """ run zzcat-mem on test.zip using archive README """ @@ -576,11 +575,10 @@ class ZZipTest(unittest.TestCase): logfile = "test2.readme.mmapped.txt" exe = self.bins("unzzipcat-mem") run = shell("{exe} {zipfile} {getfile} | tee {logfile}".format(**locals())) - run = shell("{exe} {getfile} | tee {logfile}".format(**locals())) self.assertGreater(os.path.getsize(logfile), 10) self.assertEqual(run.output.split("\n"), self.readme().split("\n")) - getfile = "test2/file.22" - run = shell("{exe} {getfile}".format(**locals())) + getfile = "file.22" + run = shell("{exe} {zipfile} {getfile}".format(**locals())) self.assertEqual("file-22\n", run.output) def test_413_zzcat_test3_zip(self): """ run zzcat-mem on test.zip using archive README """ @@ -589,11 +587,10 @@ class ZZipTest(unittest.TestCase): logfile = "test3.readme.mmapped.txt" exe = self.bins("unzzipcat-mem") run = shell("{exe} {zipfile} {getfile} | tee {logfile}".format(**locals())) - run = shell("{exe} {getfile} | tee {logfile}".format(**locals())) self.assertGreater(os.path.getsize(logfile), 10) self.assertEqual(run.output.split("\n"), self.readme().split("\n")) - getfile = "test3/file.999" - run = shell("{exe} {getfile}".format(**locals())) + getfile = "file.999" + run = shell("{exe} {zipfile} {getfile}".format(**locals())) self.assertEqual("file-999\n", run.output) def test_414_zzcat_test4_zip(self): """ run zzcat-mem on test.zip using archive README """ @@ -602,11 +599,10 @@ class ZZipTest(unittest.TestCase): logfile = "test4.readme.mmapped.txt" exe = self.bins("unzzipcat-mem") run = shell("{exe} {zipfile} {getfile} | tee {logfile}".format(**locals())) - run = shell("{exe} {getfile} | tee {logfile}".format(**locals())) self.assertGreater(os.path.getsize(logfile), 10) self.assertEqual(run.output.split("\n"), self.readme().split("\n")) - getfile = "test4/file.999" - run = shell("{exe} {getfile}".format(**locals())) + getfile = "file.999" + run = shell("{exe} {zipfile} {getfile}".format(**locals())) self.assertEqual("file-999\n", run.output) def test_420_zzdir_test0_zip(self): """ run zzdir-me on test0.zip """ diff --git a/zzip/memdisk.c b/zzip/memdisk.c index 578c0d4..0b07da7 100644 --- a/zzip/memdisk.c +++ b/zzip/memdisk.c @@ -37,6 +37,19 @@ #define ___ { #define ____ } +#define DEBUG 1 +#ifdef DEBUG +#define debug1(msg) do { fprintf(stderr, "%s : " msg "\n", __func__); } while(0) +#define debug2(msg, arg1) do { fprintf(stderr, "%s : " msg "\n", __func__, arg1); } while(0) +#define debug3(msg, arg1, arg2) do { fprintf(stderr, "%s : " msg "\n", __func__, arg1, arg2); } while(0) +#define debug4(msg, arg1, arg2, arg3) do { fprintf(stderr, "%s : " msg "\n", __func__, arg1, arg2, arg3); } while(0) +#else +#define debug1(msg) +#define debug2(msg, arg1) +#define debug3(msg, arg1, arg2) +#define debug4(msg, arg1, arg2, arg3) +#endif + static const char *error[] = { "Ok", # define _zzip_mem_disk_open_fail 1 @@ -81,7 +94,10 @@ zzip_mem_disk_open(char *filename) if (! disk) { perror(error[_zzip_mem_disk_open_fail]); return 0; } ___ ZZIP_MEM_DISK *dir = zzip_mem_disk_new(); - zzip_mem_disk_load(dir, disk); + if (zzip_mem_disk_load(dir, disk) == -1) + { + debug2("unable to load disk %s", filename); + } return dir; ____; } @@ -131,7 +147,10 @@ zzip_mem_disk_load(ZZIP_MEM_DISK * dir, ZZIP_DISK * disk) { ZZIP_MEM_ENTRY *item = zzip_mem_entry_new(disk, entry); if (! item) + { + debug1("unable to load entry"); goto error; + } if (dir->last) { dir->last->zz_next = item; /* chain last */ @@ -170,6 +189,7 @@ zzip_mem_entry_new(ZZIP_DISK * disk, ZZIP_DISK_ENTRY * entry) zzip_disk_entry_to_file_header(disk, entry); if (! header) { + debug1("no header in entry"); free (item); return 0; /* errno=EBADMSG; */ } @@ -188,7 +208,8 @@ zzip_mem_entry_new(ZZIP_DISK * disk, ZZIP_DISK_ENTRY * entry) item->zz_usize = zzip_disk_entry_get_usize(entry); item->zz_diskstart = zzip_disk_entry_get_diskstart(entry); item->zz_filetype = zzip_disk_entry_get_filetype(entry); - + + /* zz_comment and zz_name are empty strings if not present on disk */ if (! item->zz_comment || ! item->zz_name) { goto error; /* errno=ENOMEM */ diff --git a/zzip/mmapped.c b/zzip/mmapped.c index ef63a0f..67f293f 100644 --- a/zzip/mmapped.c +++ b/zzip/mmapped.c @@ -57,6 +57,18 @@ #define ____ } #endif +#ifdef DEBUG +#define debug1(msg) do { fprintf(stderr, "%s : " msg "\n", __func__); } while(0) +#define debug2(msg, arg1) do { fprintf(stderr, "%s : " msg "\n", __func__, arg1); } while(0) +#define debug3(msg, arg1, arg2) do { fprintf(stderr, "%s : " msg "\n", __func__, arg1, arg2); } while(0) +#define debug4(msg, arg1, arg2, arg3) do { fprintf(stderr, "%s : " msg "\n", __func__, arg1, arg2, arg3); } while(0) +#else +#define debug1(msg) +#define debug2(msg, arg1) +#define debug3(msg, arg1, arg2) +#define debug4(msg, arg1, arg2, arg3) +#endif + /** => zzip_disk_mmap * This function does primary initialization of a disk-buffer struct. * @@ -329,8 +341,8 @@ zzip_disk_entry_to_file_header(ZZIP_DISK * disk, struct zzip_disk_entry *entry) * in the zip central directory but if not then we fallback to the filename * given in the file_header of each compressed data portion. * - * This function returns a new string buffer, or null on error - * or when no name was there at all (errno). + * This function returns a new string buffer, or null on error. + * If no name can be found then an empty string is returned. */ zzip__new__ char * zzip_disk_entry_strdup_name(ZZIP_DISK * disk, struct zzip_disk_entry *entry) @@ -357,8 +369,7 @@ zzip_disk_entry_strdup_name(ZZIP_DISK * disk, struct zzip_disk_entry *entry) if (! len) { /* neither a name in disk_entry nor in file_header */ - errno = ENOENT; - return 0; + return strdup(""); /* ENOMEM */ } name = zzip_file_header_to_filename(file); } @@ -378,8 +389,8 @@ zzip_disk_entry_strdup_name(ZZIP_DISK * disk, struct zzip_disk_entry *entry) * This function is similar creating a reference to a zero terminated * string but it can only exist in the zip central directory entry. * - * This function returns a new string buffer, or null on error (errno) - * or if there was no comment there (errno is ENOENT). + * This function returns a new string buffer, or null on error (errno). + * If no name can be found then an empty string is returned. */ zzip__new__ char * zzip_disk_entry_strdup_comment(ZZIP_DISK * disk, struct zzip_disk_entry *entry) @@ -393,8 +404,7 @@ zzip_disk_entry_strdup_comment(ZZIP_DISK * disk, struct zzip_disk_entry *entry) ___ zzip_size_t len = zzip_disk_entry_comment(entry); if (! len) { - errno = ENOENT; - return 0; + return strdup(""); /* ENOMEM */ } ___ char *text = zzip_disk_entry_to_comment(entry); @@ -443,13 +453,16 @@ zzip_disk_entry_strdup_comment(ZZIP_DISK * disk, struct zzip_disk_entry *entry) struct zzip_disk_entry * zzip_disk_findfirst(ZZIP_DISK * disk) { + debug1("findfirst"); if (! disk) { + debug1("non arg"); errno = EINVAL; return 0; } if (disk->buffer > disk->endbuf - sizeof(struct zzip_disk_trailer)) { + debug1("not enough data for a disk trailer"); errno = EBADMSG; return 0; } @@ -460,11 +473,14 @@ zzip_disk_findfirst(ZZIP_DISK * disk) if (zzip_disk_trailer_check_magic(p)) { struct zzip_disk_trailer *trailer = (struct zzip_disk_trailer *) p; - root = disk->buffer + zzip_disk_trailer_get_rootseek(trailer); + zzip_size_t rootseek = zzip_disk_trailer_get_rootseek(trailer); + root = disk->buffer + rootseek; + debug2("disk rootseek at %lli", (long long)rootseek); if (root > p) { /* the first disk_entry is after the disk_trailer? can't be! */ zzip_size_t rootsize = zzip_disk_trailer_get_rootsize(trailer); + debug2("have rootsize at %lli", (long long)rootsize); if (disk->buffer + rootsize > p) continue; /* a common brokeness that can be fixed: we just assume the @@ -476,8 +492,14 @@ zzip_disk_findfirst(ZZIP_DISK * disk) struct zzip_disk64_trailer *trailer = (struct zzip_disk64_trailer *) p; if (sizeof(void *) < 8) - return 0; /* EOVERFLOW */ - root = disk->buffer + zzip_disk64_trailer_get_rootseek(trailer); + { + debug1("disk64 trailer in non-largefile part"); + errno = EFBIG; + return 0; + } + zzip_size_t rootseek = zzip_disk64_trailer_get_rootseek(trailer); + debug2("disk64 rootseek at %lli", (long long)rootseek); + root = disk->buffer + rootseek; if (root > p) continue; } else @@ -485,10 +507,18 @@ zzip_disk_findfirst(ZZIP_DISK * disk) continue; } + debug4("buffer %p root %p endbuf %p", disk->buffer, root, disk->endbuf); if (root < disk->buffer) - continue; + { + debug1("root before buffer should be impossible"); + errno = EBADMSG; + return 0; + } if (zzip_disk_entry_check_magic(root)) + { + debug1("found the disk root"); return (struct zzip_disk_entry *) root; + } } ____; /* not found */ errno = ENOENT; @@ -526,10 +556,9 @@ zzip_disk_findnext(ZZIP_DISK * disk, struct zzip_disk_entry *entry) zzip_disk_entry_sizeto_end(entry) > 64 * 1024 || zzip_disk_entry_skipto_end(entry) + sizeof(entry) > disk->endbuf) { - errno = EBADMSG; + errno = ENOENT; return 0; } - /* found */ return entry; } -- 2.40.0