summaryrefslogtreecommitdiff
path: root/Build/source/libs/zziplib/zziplib-0.13.58/zzip/zip.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/zziplib/zziplib-0.13.58/zzip/zip.c')
-rw-r--r--Build/source/libs/zziplib/zziplib-0.13.58/zzip/zip.c836
1 files changed, 469 insertions, 367 deletions
diff --git a/Build/source/libs/zziplib/zziplib-0.13.58/zzip/zip.c b/Build/source/libs/zziplib/zziplib-0.13.58/zzip/zip.c
index 5133a11613b..0a400cd47d8 100644
--- a/Build/source/libs/zziplib/zziplib-0.13.58/zzip/zip.c
+++ b/Build/source/libs/zziplib/zziplib-0.13.58/zzip/zip.c
@@ -1,17 +1,18 @@
+
/*
- * Author:
+ * Author:
* Guido Draheim <guidod@gmx.de>
* Tomi Ollila <too@iki.fi>
*
* Copyright (c) 1999,2000,2001,2002,2003 Guido Draheim
* All rights reserved,
- * use under the restrictions of the
+ * use under the restrictions of the
* Lesser GNU General Public License
- * or alternatively the restrictions
+ * or alternatively the restrictions
* of the Mozilla Public License 1.1
*/
-#include <zzip/lib.h> /* archive handling */
+#include <zzip/lib.h> /* archive handling */
#include <zzip/file.h>
#include <zzip/format.h>
#include <zzip/fetch.h>
@@ -42,16 +43,17 @@
#define _255 255
#endif
-#define ZZIP_DISK64_TRAILER
+#define ZZIP_DISK64_TRAILER 1
#ifdef ZZIP_DISK64_TRAILER
-struct _disk_trailer {
- void* zz_tail;
- void* zz_for_correct_rootseek; // ZZIP_CORRECT_ROOTSEEK
- zzip_off64_t zz_entries;
- zzip_off64_t zz_finalentries;
- zzip_off64_t zz_rootseek;
- zzip_off64_t zz_rootsize;
+struct _disk_trailer
+{
+ void *zz_tail;
+ void *zz_for_correct_rootseek; // ZZIP_CORRECT_ROOTSEEK
+ zzip_off64_t zz_entries;
+ zzip_off64_t zz_finalentries;
+ zzip_off64_t zz_rootseek;
+ zzip_off64_t zz_rootsize;
};
#define _disk_trailer_entries(__p) ((__p)->zz_entries)
#define _disk_trailer_localentries(__p) ((__p)->zz_entries)
@@ -72,47 +74,50 @@ struct _disk_trailer {
#endif
/* --------------------------- internals -------------------------------- */
+
/* internal functions of zziplib, avoid at all cost, changes w/o warning.
* we do export them for debugging purpose and special external tools
* which know what they do and which can adapt from version to version
*/
-int __zzip_fetch_disk_trailer( int fd, zzip_off_t filesize,
- struct _disk_trailer * _zzip_restrict trailer,
- zzip_plugin_io_t io);
-int __zzip_parse_root_directory( int fd,
- struct _disk_trailer * trailer,
- struct zzip_dir_hdr ** hdr_return,
- zzip_plugin_io_t io);
+int __zzip_fetch_disk_trailer(int fd, zzip_off_t filesize,
+ struct _disk_trailer *_zzip_restrict trailer,
+ zzip_plugin_io_t io);
+int __zzip_parse_root_directory(int fd,
+ struct _disk_trailer *trailer,
+ struct zzip_dir_hdr **hdr_return,
+ zzip_plugin_io_t io);
-_zzip_inline char* __zzip_aligned4(char* p);
+_zzip_inline char *__zzip_aligned4(char *p);
/* ------------------------ harden routines ------------------------------ */
#ifdef ZZIP_HARDEN
+
/*
* check for inconsistent values in trailer and prefer lower seek value
* - we fix values assuming the root directory was written at the end
* and it is just before the zip trailer. Therefore, ...
*/
-_zzip_inline static void __fixup_rootseek(
- zzip_off_t offset_of_trailer,
- struct _disk_trailer* trailer)
+_zzip_inline static void
+__fixup_rootseek(zzip_off_t offset_of_trailer, struct _disk_trailer *trailer)
{
- if ( _disk_trailer_rootseek (trailer) >
- offset_of_trailer - _disk_trailer_rootsize (trailer) &&
- offset_of_trailer > _disk_trailer_rootsize (trailer))
+ if (_disk_trailer_rootseek(trailer) >
+ offset_of_trailer - _disk_trailer_rootsize(trailer) &&
+ offset_of_trailer > _disk_trailer_rootsize(trailer))
{
- register zzip_off_t offset;
- offset = offset_of_trailer - _disk_trailer_rootsize (trailer);
- _disk_trailer_set_rootseek (trailer, offset);
- HINT2("new rootseek=%li", (long) _disk_trailer_rootseek (trailer));
+ register zzip_off_t offset;
+ offset = offset_of_trailer - _disk_trailer_rootsize(trailer);
+ _disk_trailer_set_rootseek(trailer, offset);
+ HINT2("new rootseek=%li", (long) _disk_trailer_rootseek(trailer));
}
}
+
#define __correct_rootseek(A,B,C)
#elif defined ZZIP_CORRECT_ROOTSEEK
-/* store the seekvalue of the trailer into the "z_magic" field and with
+
+/* store the seekvalue of the trailer into the "z_magic" field and with
* a 64bit off_t we overwrite z_disk/z_finaldisk as well. If you change
* anything in zziplib or dump the trailer structure then watch out that
* these are still unused, so that this code may still (ab)use those. */
@@ -122,25 +127,28 @@ _zzip_inline static void __fixup_rootseek(
if (_u_rootseek > *(zzip_off_t*)_trailer - _u_rootsize) \
_u_rootseek = *(zzip_off_t*)_trailer - _u_rootsize;
#else
-#define __fixup_rootseek(A,B)
+#define __fixup_rootseek(A,B)
#define __correct_rootseek(A,B,C)
#endif
#ifdef DEBUG
-_zzip_inline static void __debug_dir_hdr (struct zzip_dir_hdr* hdr)
+_zzip_inline static void
+__debug_dir_hdr(struct zzip_dir_hdr *hdr)
{
if (sizeof(struct zzip_dir_hdr) > sizeof(struct zzip_disk_entry))
- { WARN1("internal sizeof-mismatch may break wreakage"); }
+ { WARN1("internal sizeof-mismatch may break wreakage"); }
/* the internal directory structure is never bigger than the
* external zip central directory space had been beforehand
- * (as long as the following assertion holds...)
+ * (as long as the following assertion holds...)
*/
- if (((zzip_off_t)hdr)&3)
- { NOTE1("this machine's malloc(3) returns sth. not u32-aligned"); }
- /* we assume that if this machine's malloc has returned a non-aligned
- * memory block, then it is actually safe to access misaligned data, and
+ if (((zzip_off_t) hdr) & 3)
+ {
+ NOTE1("this machine's malloc(3) returns sth. not u32-aligned");
+ }
+ /* we assume that if this machine's malloc has returned a non-aligned
+ * memory block, then it is actually safe to access misaligned data, and
* since it does only affect the first hdr it should not even bring about
* too much of that cpu's speed penalty
*/
@@ -151,7 +159,7 @@ _zzip_inline static void __debug_dir_hdr (struct zzip_dir_hdr* hdr)
/* -------------------------- low-level interface -------------------------- */
-#if defined BUFSIZ
+#if defined BUFSIZ
#if BUFSIZ == 1024 || BUFSIZ == 512 || BUFSIZ == 256
#define ZZIP_BUFSIZ BUFSIZ
#endif
@@ -159,7 +167,8 @@ _zzip_inline static void __debug_dir_hdr (struct zzip_dir_hdr* hdr)
#ifndef ZZIP_BUFSIZ
#define ZZIP_BUFSIZ 512
-/* #define ZZIP_BUFSIZ 64 */ /* for testing */
+
+/* #define ZZIP_BUFSIZ 64 / * for testing */
#endif
/**
@@ -167,10 +176,10 @@ _zzip_inline static void __debug_dir_hdr (struct zzip_dir_hdr* hdr)
* the zip's central directory info that is usually a few
* bytes off the end of the file.
*/
-int
-__zzip_fetch_disk_trailer(int fd, zzip_off_t filesize,
- struct _disk_trailer * _zzip_restrict trailer,
- zzip_plugin_io_t io)
+int
+__zzip_fetch_disk_trailer(int fd, zzip_off_t filesize,
+ struct _disk_trailer *_zzip_restrict trailer,
+ zzip_plugin_io_t io)
{
#ifdef DEBUG
#define return(val) { e=val; HINT2("%s", zzip_strerror(e)); goto cleanup; }
@@ -178,161 +187,185 @@ __zzip_fetch_disk_trailer(int fd, zzip_off_t filesize,
#define return(val) { e=val; goto cleanup; }
#endif
register int e;
-
+
#ifndef _LOWSTK
- auto char buffer[2*ZZIP_BUFSIZ];
- char* buf = buffer;
+ auto char buffer[2 * ZZIP_BUFSIZ];
+ char *buf = buffer;
#else
- char* buf = malloc(2*ZZIP_BUFSIZ);
+ char *buf = malloc(2 * ZZIP_BUFSIZ);
#endif
zzip_off_t offset = 0;
- zzip_ssize_t maplen = 0; /* mmap(),read(),getpagesize() use size_t !! */
- char* fd_map = 0;
+ zzip_ssize_t maplen = 0; /* mmap(),read(),getpagesize() use size_t !! */
+ char *fd_map = 0;
- if (!trailer)
+ if (! trailer)
{ return(EINVAL); }
-
+
if (filesize < __sizeof(struct zzip_disk_trailer))
- { return(ZZIP_DIR_TOO_SHORT); }
-
- if (!buf)
+ { return(ZZIP_DIR_TOO_SHORT); }
+
+ if (! buf)
{ return(ZZIP_OUTOFMEM); }
- offset = filesize; /* a.k.a. old offset */
- while(1) /* outer loop */
+ offset = filesize; /* a.k.a. old offset */
+ while (1) /* outer loop */
{
- register unsigned char* mapped;
+ register unsigned char *mapped;
- if (offset <= 0) { return(ZZIP_DIR_EDH_MISSING); }
+ if (offset <= 0)
+ { return(ZZIP_DIR_EDH_MISSING); }
- /* trailer cannot be farther away than 64K from fileend */
- if (filesize-offset > 64*1024)
- { return(ZZIP_DIR_EDH_MISSING); }
+ /* trailer cannot be farther away than 64K from fileend */
+ if (filesize - offset > 64 * 1024)
+ { return(ZZIP_DIR_EDH_MISSING); }
- /* the new offset shall overlap with the area after the old offset! */
+ /* the new offset shall overlap with the area after the old offset! */
if (USE_MMAP && io->fd.sys)
{
- zzip_off_t mapoff = offset;
- {
- zzip_ssize_t pagesize = _zzip_getpagesize (io->fd.sys);
- if (pagesize < ZZIP_BUFSIZ) goto non_mmap; /* an error? */
- if (mapoff == filesize && filesize > pagesize)
- mapoff -= pagesize;
- if (mapoff < pagesize) {
- maplen = (zzip_ssize_t)mapoff + pagesize; mapoff = 0;
- } else {
- mapoff -= pagesize; maplen = 2*pagesize;
- if ((zzip_ssize_t)mapoff & (pagesize-1)) { /*only 1. run */
- pagesize -= (zzip_ssize_t)mapoff & (pagesize-1);
- mapoff += pagesize;
- maplen -= pagesize;
- }
- }
- if (mapoff + maplen > filesize) maplen = filesize - mapoff;
- }
-
- fd_map = _zzip_mmap(io->fd.sys, fd, mapoff, (zzip_size_t)maplen);
- if (fd_map == MAP_FAILED) goto non_mmap;
- mapped = (unsigned char*) fd_map; offset = mapoff; /* success */
- HINT3("mapped *%p len=%li", fd_map, (long) maplen);
- } else {
- non_mmap:
- fd_map = 0; /* have no mmap */
- {
- zzip_off_t pagesize = ZZIP_BUFSIZ;
- if (offset == filesize && filesize > pagesize)
- offset -= pagesize;
- if (offset < pagesize) {
- maplen = (zzip_ssize_t)offset + pagesize; offset = 0;
- } else {
- offset -= pagesize; maplen = 2*pagesize;
- if ((zzip_ssize_t)offset & (pagesize-1)) { /*on 1st run*/
- pagesize -= (zzip_ssize_t)offset & (pagesize-1);
- offset += pagesize;
- maplen -= pagesize;
- }
- }
- if (offset + maplen > filesize) maplen = filesize - offset;
- }
-
+ zzip_off_t mapoff = offset;
+ {
+ zzip_ssize_t pagesize = _zzip_getpagesize(io->fd.sys);
+ if (pagesize < ZZIP_BUFSIZ)
+ goto non_mmap; /* an error? */
+ if (mapoff == filesize && filesize > pagesize)
+ mapoff -= pagesize;
+ if (mapoff < pagesize)
+ {
+ maplen = (zzip_ssize_t) mapoff + pagesize;
+ mapoff = 0;
+ } else
+ {
+ mapoff -= pagesize;
+ maplen = 2 * pagesize;
+ if ((zzip_ssize_t) mapoff & (pagesize - 1))
+ { /*only 1. run */
+ pagesize -= (zzip_ssize_t) mapoff & (pagesize - 1);
+ mapoff += pagesize;
+ maplen -= pagesize;
+ }
+ }
+ if (mapoff + maplen > filesize)
+ maplen = filesize - mapoff;
+ }
+
+ fd_map = _zzip_mmap(io->fd.sys, fd, mapoff, (zzip_size_t) maplen);
+ if (fd_map == MAP_FAILED)
+ goto non_mmap;
+ mapped = (unsigned char *) fd_map;
+ offset = mapoff; /* success */
+ HINT3("mapped *%p len=%li", fd_map, (long) maplen);
+ } else
+ {
+ non_mmap:
+ fd_map = 0; /* have no mmap */
+ {
+ zzip_off_t pagesize = ZZIP_BUFSIZ;
+ if (offset == filesize && filesize > pagesize)
+ offset -= pagesize;
+ if (offset < pagesize)
+ {
+ maplen = (zzip_ssize_t) offset + pagesize;
+ offset = 0;
+ } else
+ {
+ offset -= pagesize;
+ maplen = 2 * pagesize;
+ if ((zzip_ssize_t) offset & (pagesize - 1))
+ { /*on 1st run */
+ pagesize -= (zzip_ssize_t) offset & (pagesize - 1);
+ offset += pagesize;
+ maplen -= pagesize;
+ }
+ }
+ if (offset + maplen > filesize)
+ maplen = filesize - offset;
+ }
+
if (io->fd.seeks(fd, offset, SEEK_SET) < 0)
{ return(ZZIP_DIR_SEEK); }
- if (io->fd.read(fd, buf, (zzip_size_t)maplen) < maplen)
+ if (io->fd.read(fd, buf, (zzip_size_t) maplen) < maplen)
{ return(ZZIP_DIR_READ); }
- mapped = (unsigned char*) buf; /* success */
- HINT5("offs=$%lx len=%li filesize=%li pagesize=%i",
- (long)offset, (long)maplen, (long)filesize, ZZIP_BUFSIZ);
+ mapped = (unsigned char *) buf; /* success */
+ HINT5("offs=$%lx len=%li filesize=%li pagesize=%i",
+ (long) offset, (long) maplen, (long) filesize, ZZIP_BUFSIZ);
}
- {/* now, check for the trailer-magic, hopefully near the end of file */
- register unsigned char* end = mapped + maplen;
- register unsigned char* tail;
- for (tail = end-1; (tail >= mapped); tail--)
- {
- if ((*tail == 'P') && /* quick pre-check for trailer magic */
- end-tail >= __sizeof(struct zzip_disk_trailer)-2 &&
- zzip_disk_trailer_check_magic(tail))
- {
+ { /* now, check for the trailer-magic, hopefully near the end of file */
+ register unsigned char *end = mapped + maplen;
+ register unsigned char *tail;
+ for (tail = end - 1; (tail >= mapped); tail--)
+ {
+ if ((*tail == 'P') && /* quick pre-check for trailer magic */
+ end - tail >= __sizeof(struct zzip_disk_trailer) - 2 &&
+ zzip_disk_trailer_check_magic(tail))
+ {
# ifndef ZZIP_DISK64_TRAILER
- /* if the file-comment is not present, it happens
- that the z_comment field often isn't either */
- if (end-tail >= __sizeof(*trailer))
- {
- memcpy (trailer, tail, sizeof(*trailer));
- }else{
- memcpy (trailer, tail, sizeof(*trailer)-2);
- trailer->z_comment[0] = 0;
- trailer->z_comment[1] = 0;
- }
+ /* if the file-comment is not present, it happens
+ that the z_comment field often isn't either */
+ if (end - tail >= __sizeof(*trailer))
+ {
+ memcpy(trailer, tail, sizeof(*trailer));
+ } else
+ {
+ memcpy(trailer, tail, sizeof(*trailer) - 2);
+ trailer->z_comment[0] = 0;
+ trailer->z_comment[1] = 0;
+ }
# else
- struct zzip_disk_trailer* orig = (struct zzip_disk_trailer*) tail;
- trailer->zz_tail = tail;
- trailer->zz_entries = zzip_disk_trailer_localentries (orig);
- trailer->zz_finalentries = zzip_disk_trailer_finalentries (orig);
- trailer->zz_rootseek = zzip_disk_trailer_rootseek (orig);
- trailer->zz_rootsize = zzip_disk_trailer_rootsize (orig);
+ struct zzip_disk_trailer *orig =
+ (struct zzip_disk_trailer *) tail;
+ trailer->zz_tail = tail;
+ trailer->zz_entries = zzip_disk_trailer_localentries(orig);
+ trailer->zz_finalentries =
+ zzip_disk_trailer_finalentries(orig);
+ trailer->zz_rootseek = zzip_disk_trailer_rootseek(orig);
+ trailer->zz_rootsize = zzip_disk_trailer_rootsize(orig);
# endif
- __fixup_rootseek (offset + tail-mapped, trailer);
- { return(0); }
- } else if ((*tail == 'P') &&
- end-tail >= __sizeof(struct zzip_disk64_trailer)-2 &&
- zzip_disk64_trailer_check_magic(tail))
- {
+ __fixup_rootseek(offset + tail - mapped, trailer);
+ { return(0); }
+ } else if ((*tail == 'P') &&
+ end - tail >=
+ __sizeof(struct zzip_disk64_trailer) - 2
+ && zzip_disk64_trailer_check_magic(tail))
+ {
# ifndef ZZIP_DISK64_TRAILER
- return(ZZIP_DIR_LARGEFILE);
+ return (ZZIP_DIR_LARGEFILE);
# else
- struct zzip_disk64_trailer* orig = (struct zzip_disk64_trailer*) tail;
- trailer->zz_tail = tail;
- trailer->zz_entries = zzip_disk64_trailer_localentries (orig);
- trailer->zz_finalentries = zzip_disk64_trailer_finalentries (orig);
- trailer->zz_rootseek = zzip_disk64_trailer_rootseek (orig);
- trailer->zz_rootsize = zzip_disk64_trailer_rootsize (orig);
- { return(0); }
+ struct zzip_disk64_trailer *orig =
+ (struct zzip_disk64_trailer *) tail;
+ trailer->zz_tail = tail;
+ trailer->zz_entries =
+ zzip_disk64_trailer_localentries(orig);
+ trailer->zz_finalentries =
+ zzip_disk64_trailer_finalentries(orig);
+ trailer->zz_rootseek = zzip_disk64_trailer_rootseek(orig);
+ trailer->zz_rootsize = zzip_disk64_trailer_rootsize(orig);
+ { return(0); }
# endif
- }
- }
+ }
+ }
+ }
+
+ if (USE_MMAP && fd_map)
+ {
+ HINT3("unmap *%p len=%li", fd_map, (long) maplen);
+ _zzip_munmap(io->fd.sys, fd_map, (zzip_size_t) maplen);
+ fd_map = 0;
}
-
- if (USE_MMAP && fd_map)
- {
- HINT3("unmap *%p len=%li", fd_map, (long) maplen);
- _zzip_munmap(io->fd.sys, fd_map, (zzip_size_t)maplen);
- fd_map = 0;
- }
- } /*outer loop*/
-
- cleanup:
+ } /*outer loop */
+
+ cleanup:
if (USE_MMAP && fd_map)
- {
- HINT3("unmap *%p len=%li", fd_map, (long) maplen);
- _zzip_munmap(io->fd.sys, fd_map, (zzip_size_t)maplen);
+ {
+ HINT3("unmap *%p len=%li", fd_map, (long) maplen);
+ _zzip_munmap(io->fd.sys, fd_map, (zzip_size_t) maplen);
}
# ifdef _LOWSTK
free(buf);
# endif
# undef return
- return e;
+ return e;
}
/*
@@ -342,11 +375,12 @@ __zzip_fetch_disk_trailer(int fd, zzip_off_t filesize,
* to pointer types but we do need only the lower bits in this implementation,
* so we can just cast the value to a long value.
*/
-_zzip_inline char* __zzip_aligned4(char* p)
+_zzip_inline char *
+__zzip_aligned4(char *p)
{
#define aligned4 __zzip_aligned4
- p += ((long)p)&1; /* warnings about truncation of a "pointer" */
- p += ((long)p)&2; /* to a "long int" may be safely ignored :) */
+ p += ((long) p) & 1; /* warnings about truncation of a "pointer" */
+ p += ((long) p) & 2; /* to a "long int" may be safely ignored :) */
return p;
}
@@ -356,76 +390,102 @@ _zzip_inline char* __zzip_aligned4(char* p)
* information and create a zziplib private directory table in
* memory.
*/
-int
-__zzip_parse_root_directory(int fd,
- struct _disk_trailer * trailer,
- struct zzip_dir_hdr ** hdr_return,
- zzip_plugin_io_t io)
+int
+__zzip_parse_root_directory(int fd,
+ struct _disk_trailer *trailer,
+ struct zzip_dir_hdr **hdr_return,
+ zzip_plugin_io_t io)
{
auto struct zzip_disk_entry dirent;
- struct zzip_dir_hdr * hdr;
- struct zzip_dir_hdr * hdr0;
- uint16_t * p_reclen = 0;
- unsigned long entries; /* 32bit is enough */
- zzip_off64_t zz_offset; /* offset from start of root directory */
- char* fd_map = 0;
+ struct zzip_dir_hdr *hdr;
+ struct zzip_dir_hdr *hdr0;
+ uint16_t *p_reclen = 0;
+ zzip_off64_t entries;
+ zzip_off64_t zz_offset; /* offset from start of root directory */
+ char *fd_map = 0;
zzip_off64_t zz_fd_gap = 0;
- zzip_off64_t zz_entries = _disk_trailer_localentries (trailer);
- zzip_off64_t zz_rootsize = _disk_trailer_rootsize (trailer);
- zzip_off64_t zz_rootseek = _disk_trailer_rootseek (trailer);
- __correct_rootseek (zz_rootseek, zz_rootsize, trailer);
+ zzip_off64_t zz_entries = _disk_trailer_localentries(trailer);
+ zzip_off64_t zz_rootsize = _disk_trailer_rootsize(trailer);
+ zzip_off64_t zz_rootseek = _disk_trailer_rootseek(trailer);
+ __correct_rootseek(zz_rootseek, zz_rootsize, trailer);
- hdr0 = (struct zzip_dir_hdr*) malloc(zz_rootsize);
- if (!hdr0)
+ hdr0 = (struct zzip_dir_hdr *) malloc(zz_rootsize);
+ if (! hdr0)
return ZZIP_DIRSIZE;
- hdr = hdr0; __debug_dir_hdr (hdr);
+ hdr = hdr0;
+ __debug_dir_hdr(hdr);
if (USE_MMAP && io->fd.sys)
{
- zz_fd_gap = zz_rootseek & (_zzip_getpagesize(io->fd.sys)-1) ;
- HINT4(" fd_gap=%ld, mapseek=0x%lx, maplen=%ld", (long)(zz_fd_gap),
- (long)(zz_rootseek-zz_fd_gap), (long)(zz_rootsize+zz_fd_gap));
- fd_map = _zzip_mmap(io->fd.sys, fd,
- zz_rootseek-zz_fd_gap, zz_rootsize+zz_fd_gap);
+ zz_fd_gap = zz_rootseek & (_zzip_getpagesize(io->fd.sys) - 1);
+ HINT4(" fd_gap=%ld, mapseek=0x%lx, maplen=%ld", (long) (zz_fd_gap),
+ (long) (zz_rootseek - zz_fd_gap),
+ (long) (zz_rootsize + zz_fd_gap));
+ fd_map =
+ _zzip_mmap(io->fd.sys, fd, zz_rootseek - zz_fd_gap,
+ zz_rootsize + zz_fd_gap);
/* if mmap failed we will fallback to seek/read mode */
- if (fd_map == MAP_FAILED) {
- NOTE2("map failed: %s",strerror(errno));
- fd_map=0;
- }else{
- HINT3("mapped *%p len=%li", fd_map, (long)(zz_rootsize+zz_fd_gap));
- }
+ if (fd_map == MAP_FAILED)
+ {
+ NOTE2("map failed: %s", strerror(errno));
+ fd_map = 0;
+ } else
+ {
+ HINT3("mapped *%p len=%li", fd_map,
+ (long) (zz_rootsize + zz_fd_gap));
+ }
}
- for (entries=zz_entries, zz_offset=0; entries; entries--)
+ for (entries=0, zz_offset=0; ; entries++)
{
- register struct zzip_disk_entry * d;
+ register struct zzip_disk_entry *d;
uint16_t u_extras, u_comment, u_namlen;
- if (fd_map)
- { d = (void*)(fd_map+zz_fd_gap+zz_offset); } /* fd_map+fd_gap==u_rootseek */
+# ifndef ZZIP_ALLOW_MODULO_ENTRIES
+ if (entries >= zz_entries) {
+ if (zz_offset + 256 < zz_rootsize) {
+ FAIL4("%li's entry is long before the end of directory - enable modulo_entries? (O:%li R:%li)",
+ (long) entries, (long) (zz_offset), (long) zz_rootsize);
+ }
+ break;
+ }
+# endif
+
+ if (fd_map)
+ { d = (void*)(fd_map+zz_fd_gap+zz_offset); } /* fd_map+fd_gap==u_rootseek */
else
{
- if (io->fd.seeks(fd, zz_rootseek+zz_offset, SEEK_SET) < 0)
+ if (io->fd.seeks(fd, zz_rootseek + zz_offset, SEEK_SET) < 0)
return ZZIP_DIR_SEEK;
if (io->fd.read(fd, &dirent, sizeof(dirent)) < __sizeof(dirent))
return ZZIP_DIR_READ;
d = &dirent;
}
- if ((zzip_off64_t)(zz_offset+sizeof(*d)) > zz_rootsize ||
- (zzip_off64_t)(zz_offset+sizeof(*d)) < 0)
- { FAIL4("%li's entry stretches beyond root directory (O:%li R:%li)",
- (long)entries, (long)(zz_offset), (long)zz_rootsize); break;}
+ if (! zzip_disk_entry_check_magic(d)) {
+# ifndef ZZIP_ALLOW_MODULO_ENTRIES
+ FAIL4("%li's entry has no disk_entry magic indicator (O:%li R:%li)",
+ (long) entries, (long) (zz_offset), (long) zz_rootsize);
+# endif
+ break;
+ }
+ if ((zzip_off64_t) (zz_offset + sizeof(*d)) > zz_rootsize ||
+ (zzip_off64_t) (zz_offset + sizeof(*d)) < 0)
+ {
+ FAIL4("%li's entry stretches beyond root directory (O:%li R:%li)",
+ (long) entries, (long) (zz_offset), (long) zz_rootsize);
+ break;
+ }
# if 0 && defined DEBUG
- zzip_debug_xbuf ((unsigned char*) d, sizeof(*d) + 8);
-# endif
-
- u_extras = zzip_disk_entry_get_extras (d);
- u_comment = zzip_disk_entry_get_comment (d);
- u_namlen = zzip_disk_entry_get_namlen (d);
+ zzip_debug_xbuf((unsigned char *) d, sizeof(*d) + 8);
+# endif
+
+ u_extras = zzip_disk_entry_get_extras(d);
+ u_comment = zzip_disk_entry_get_comment(d);
+ u_namlen = zzip_disk_entry_get_namlen(d);
HINT5("offset=0x%lx, size %ld, dirent *%p, hdr %p\n",
- (long)(zz_offset+zz_rootseek), (long)zz_rootsize, d, hdr);
+ (long) (zz_offset + zz_rootseek), (long) zz_rootsize, d, hdr);
/* writes over the read buffer, Since the structure where data is
copied is smaller than the data in buffer this can be done.
@@ -434,61 +494,75 @@ __zzip_parse_root_directory(int fd,
first structure read.
at the end the whole copied list of structures is copied into
newly allocated buffer */
- hdr->d_crc32 = zzip_disk_entry_get_crc32 (d);
- hdr->d_csize = zzip_disk_entry_get_csize (d);
- hdr->d_usize = zzip_disk_entry_get_usize (d);
- hdr->d_off = zzip_disk_entry_get_offset (d);
- hdr->d_compr = zzip_disk_entry_get_compr (d);
- if (hdr->d_compr > _255) hdr->d_compr = 255;
-
- if ((zzip_off64_t)(zz_offset+sizeof(*d) + u_namlen) > zz_rootsize ||
- (zzip_off64_t)(zz_offset+sizeof(*d) + u_namlen) < 0)
- { FAIL4("%li's name stretches beyond root directory (O:%li N:%li)",
- (long)entries, (long)(zz_offset), (long)(u_namlen)); break; }
-
- if (fd_map)
- { memcpy(hdr->d_name, fd_map+zz_fd_gap + zz_offset+sizeof(*d), u_namlen); }
- else { io->fd.read(fd, hdr->d_name, u_namlen); }
- hdr->d_name[u_namlen] = '\0';
+ hdr->d_crc32 = zzip_disk_entry_get_crc32(d);
+ hdr->d_csize = zzip_disk_entry_get_csize(d);
+ hdr->d_usize = zzip_disk_entry_get_usize(d);
+ hdr->d_off = zzip_disk_entry_get_offset(d);
+ hdr->d_compr = zzip_disk_entry_get_compr(d);
+ if (hdr->d_compr > _255)
+ hdr->d_compr = 255;
+
+ if ((zzip_off64_t) (zz_offset + sizeof(*d) + u_namlen) > zz_rootsize ||
+ (zzip_off64_t) (zz_offset + sizeof(*d) + u_namlen) < 0)
+ {
+ FAIL4("%li's name stretches beyond root directory (O:%li N:%li)",
+ (long) entries, (long) (zz_offset), (long) (u_namlen));
+ break;
+ }
+
+ if (fd_map)
+ { memcpy(hdr->d_name, fd_map+zz_fd_gap + zz_offset+sizeof(*d), u_namlen); }
+ else
+ { io->fd.read(fd, hdr->d_name, u_namlen); }
+ hdr->d_name[u_namlen] = '\0';
hdr->d_namlen = u_namlen;
-
+
/* update offset by the total length of this entry -> next entry */
zz_offset += sizeof(*d) + u_namlen + u_extras + u_comment;
-
+
if (zz_offset > zz_rootsize)
- { FAIL3("%li's entry stretches beyond root directory (O:%li)",
- (long)entries, (long)(zz_offset)); entries--; break; }
-
- HINT5("file %ld { compr=%d crc32=$%x offset=%d",
- (long)entries, hdr->d_compr, hdr->d_crc32, hdr->d_off);
- HINT5("csize=%d usize=%d namlen=%d extras=%d",
- hdr->d_csize, hdr->d_usize, u_namlen, u_extras);
- HINT5("comment=%d name='%s' %s <sizeof %d> } ",
- u_comment, hdr->d_name, "",(int) sizeof(*d));
-
+ {
+ FAIL3("%li's entry stretches beyond root directory (O:%li)",
+ (long) entries, (long) (zz_offset));
+ entries ++;
+ break;
+ }
+
+ HINT5("file %ld { compr=%d crc32=$%x offset=%d",
+ (long) entries, hdr->d_compr, hdr->d_crc32, hdr->d_off);
+ HINT5("csize=%d usize=%d namlen=%d extras=%d",
+ hdr->d_csize, hdr->d_usize, u_namlen, u_extras);
+ HINT5("comment=%d name='%s' %s <sizeof %d> } ",
+ u_comment, hdr->d_name, "", (int) sizeof(*d));
+
p_reclen = &hdr->d_reclen;
-
- { register char* p = (char*) hdr;
- register char* q = aligned4 (p + sizeof(*hdr) + u_namlen + 1);
- *p_reclen = (uint16_t)(q - p);
- hdr = (struct zzip_dir_hdr*) q;
+
+ {
+ register char *p = (char *) hdr;
+ register char *q = aligned4(p + sizeof(*hdr) + u_namlen + 1);
+ *p_reclen = (uint16_t) (q - p);
+ hdr = (struct zzip_dir_hdr *) q;
}
- }/*for*/
-
- if (USE_MMAP && fd_map)
+ } /*for */
+
+ if (USE_MMAP && fd_map)
{
- HINT3("unmap *%p len=%li", fd_map, (long)(zz_rootsize+zz_fd_gap));
- _zzip_munmap(io->fd.sys, fd_map, zz_rootsize+zz_fd_gap);
+ HINT3("unmap *%p len=%li", fd_map, (long) (zz_rootsize + zz_fd_gap));
+ _zzip_munmap(io->fd.sys, fd_map, zz_rootsize + zz_fd_gap);
}
-
+
if (p_reclen)
{
- *p_reclen = 0; /* mark end of list */
-
- if (hdr_return)
- *hdr_return = hdr0;
- } /* else zero (sane) entries */
- return (entries ? ZZIP_CORRUPTED : 0);
+ *p_reclen = 0; /* mark end of list */
+
+ if (hdr_return)
+ *hdr_return = hdr0;
+ } /* else zero (sane) entries */
+# ifndef ZZIP_ALLOW_MODULO_ENTRIES
+ return (entries != zz_entries ? ZZIP_CORRUPTED : 0);
+# else
+ return (entries & (unsigned)0xFFFF) != zz_entries ? ZZIP_CORRUPTED : 0);
+# endif
}
/* ------------------------- high-level interface ------------------------- */
@@ -497,39 +571,41 @@ __zzip_parse_root_directory(int fd,
#define O_BINARY 0
#endif
-static zzip_strings_t* zzip_get_default_ext(void)
+static zzip_strings_t *
+zzip_get_default_ext(void)
{
- static zzip_strings_t ext [] =
- {
+ static zzip_strings_t ext[] = {
+ /* *INDENT-OFF* */
".zip", ".ZIP", /* common extension */
-# ifdef ZZIP_USE_ZIPLIKES
+# ifdef ZZIP_USE_ZIPLIKES
".pk3", ".PK3", /* ID Software's Quake3 zipfiles */
- ".jar", ".JAR", /* Java zipfiles */
-# endif
- 0
+ ".jar", ".JAR", /* Java zipfiles */
+# endif
+ /* *INDENT-ON* */
+ 0
};
return ext;
}
/**
- * allocate a new ZZIP_DIR handle and do basic
+ * allocate a new ZZIP_DIR handle and do basic
* initializations before usage by => zzip_dir_fdopen
* => zzip_dir_open => zzip_file_open or through
* => zzip_open
* (ext==null flags uses { ".zip" , ".ZIP" } )
* (io ==null flags use of posix io defaults)
*/
-ZZIP_DIR*
-zzip_dir_alloc_ext_io (zzip_strings_t* ext, const zzip_plugin_io_t io)
+ZZIP_DIR *
+zzip_dir_alloc_ext_io(zzip_strings_t * ext, const zzip_plugin_io_t io)
{
- ZZIP_DIR* dir;
- if ((dir = (ZZIP_DIR *)calloc(1, sizeof(*dir))) == NULL)
- return 0;
+ ZZIP_DIR *dir;
+ if ((dir = (ZZIP_DIR *) calloc(1, sizeof(*dir))) == NULL)
+ return 0;
/* dir->fileext is currently unused - so what, still initialize it */
dir->fileext = ext ? ext : zzip_get_default_ext();
- dir->io = io ? io : zzip_get_default_io ();
+ dir->io = io ? io : zzip_get_default_io();
return dir;
}
@@ -539,103 +615,111 @@ zzip_dir_alloc_ext_io (zzip_strings_t* ext, const zzip_plugin_io_t io)
* use => zzip_dir_alloc_ext_io now on explicitly, just set that second
* argument to zero to achieve the same functionality as the old style.
*/
-ZZIP_DIR*
-zzip_dir_alloc (zzip_strings_t* fileext)
+ZZIP_DIR *
+zzip_dir_alloc(zzip_strings_t * fileext)
{
- return zzip_dir_alloc_ext_io (fileext, 0);
+ return zzip_dir_alloc_ext_io(fileext, 0);
}
/**
- * will free the zzip_dir handle unless there are still
+ * will free the zzip_dir handle unless there are still
* zzip_files attached (that may use its cache buffer).
* This is the inverse of => zzip_dir_alloc , and both
* are helper functions used implicitly in other zzipcalls
- * e.g. => zzip_dir_close = zzip_close
+ * e.g. => zzip_dir_close = zzip_close
*
* returns zero on sucess
* returns the refcount when files are attached.
*/
-int
+int
zzip_dir_free(ZZIP_DIR * dir)
{
if (dir->refcount)
return (dir->refcount); /* still open files attached */
- if (dir->fd >= 0) dir->io->fd.close(dir->fd);
- if (dir->hdr0) free(dir->hdr0);
- if (dir->cache.fp) free(dir->cache.fp);
- if (dir->cache.buf32k) free(dir->cache.buf32k);
- if (dir->realname) free(dir->realname);
+ if (dir->fd >= 0)
+ dir->io->fd.close(dir->fd);
+ if (dir->hdr0)
+ free(dir->hdr0);
+ if (dir->cache.fp)
+ free(dir->cache.fp);
+ if (dir->cache.buf32k)
+ free(dir->cache.buf32k);
+ if (dir->realname)
+ free(dir->realname);
free(dir);
return 0;
}
/** => zzip_dir_free
- * It will also => free(2) the => ZZIP_DIR-handle given.
+ * It will also => free(2) the => ZZIP_DIR-handle given.
* the counterpart for => zzip_dir_open
* see also => zzip_dir_free
*/
-int
+int
zzip_dir_close(ZZIP_DIR * dir)
{
- dir->refcount &=~ 0x10000000; /* explicit dir close */
+ dir->refcount &= ~0x10000000; /* explicit dir close */
return zzip_dir_free(dir);
}
-/**
+/**
* used by the => zzip_dir_open and zzip_opendir(2) call. Opens the
* zip-archive as specified with the fd which points to an
* already openend file. This function then search and parse
* the zip's central directory.
- *
- * NOTE: refcount is zero, so an _open/_close pair will also delete
- * this _dirhandle
+ *
+ * NOTE: refcount is zero, so an _open/_close pair will also delete
+ * this _dirhandle
*/
-ZZIP_DIR *
+ZZIP_DIR *
zzip_dir_fdopen(int fd, zzip_error_t * errcode_p)
{
return zzip_dir_fdopen_ext_io(fd, errcode_p, 0, 0);
}
-static zzip_error_t __zzip_dir_parse (ZZIP_DIR* dir); /* forward */
+static zzip_error_t __zzip_dir_parse(ZZIP_DIR * dir); /* forward */
/** => zzip_dir_fdopen
- * this function uses explicit ext and io instead of the internal
+ * this function uses explicit ext and io instead of the internal
* defaults, setting these to zero is equivalent to => zzip_dir_fdopen
*/
-ZZIP_DIR *
+ZZIP_DIR *
zzip_dir_fdopen_ext_io(int fd, zzip_error_t * errcode_p,
- zzip_strings_t* ext, const zzip_plugin_io_t io)
+ zzip_strings_t * ext, const zzip_plugin_io_t io)
{
zzip_error_t rv;
- ZZIP_DIR * dir;
+ ZZIP_DIR *dir;
- if ((dir = zzip_dir_alloc_ext_io (ext, io)) == NULL)
+ if ((dir = zzip_dir_alloc_ext_io(ext, io)) == NULL)
{ rv = ZZIP_OUTOFMEM; goto error; }
dir->fd = fd;
- if ((rv = __zzip_dir_parse (dir)))
- goto error;
+ if ((rv = __zzip_dir_parse(dir)))
+ goto error;
dir->hdr = dir->hdr0;
- dir->refcount |= 0x10000000;
-
- if (errcode_p) *errcode_p = rv;
+ dir->refcount |= 0x10000000;
+
+ if (errcode_p)
+ *errcode_p = rv;
return dir;
-error:
- if (dir) zzip_dir_free(dir);
- if (errcode_p) *errcode_p = rv;
+ error:
+ if (dir)
+ zzip_dir_free(dir);
+ if (errcode_p)
+ *errcode_p = rv;
return NULL;
}
static zzip_error_t
-__zzip_dir_parse (ZZIP_DIR* dir)
+__zzip_dir_parse(ZZIP_DIR * dir)
{
zzip_error_t rv;
zzip_off_t filesize;
struct _disk_trailer trailer;
- /* if (! dir || dir->fd < 0)
- * { rv = EINVAL; goto error; }
+ /* if (! dir || dir->fd < 0)
+ * { rv = EINVAL; goto error; }
*/
HINT2("------------------ fd=%i", (int) dir->fd);
@@ -643,116 +727,134 @@ __zzip_dir_parse (ZZIP_DIR* dir)
{ rv = ZZIP_DIR_STAT; goto error; }
HINT2("------------------ filesize=%ld", (long) filesize);
- if ((rv = __zzip_fetch_disk_trailer(dir->fd, filesize, &trailer,
- dir->io)) != 0)
+ if ((rv = __zzip_fetch_disk_trailer(dir->fd, filesize, &trailer,
+ dir->io)) != 0)
{ goto error; }
-
- HINT5("directory = { entries= %ld/%ld, size= %ld, seek= %ld } ",
- (long) _disk_trailer_localentries (&trailer),
- (long) _disk_trailer_finalentries (&trailer),
- (long) _disk_trailer_rootsize (&trailer),
- (long) _disk_trailer_rootseek (&trailer));
-
- if ( (rv = __zzip_parse_root_directory(dir->fd, &trailer, &dir->hdr0,
- dir->io)) != 0)
+
+ HINT5("directory = { entries= %ld/%ld, size= %ld, seek= %ld } ",
+ (long) _disk_trailer_localentries(&trailer),
+ (long) _disk_trailer_finalentries(&trailer),
+ (long) _disk_trailer_rootsize(&trailer),
+ (long) _disk_trailer_rootseek(&trailer));
+
+ if ((rv = __zzip_parse_root_directory(dir->fd, &trailer, &dir->hdr0,
+ dir->io)) != 0)
{ goto error; }
- error:
+ error:
return rv;
}
/**
- * will attach a .zip extension and tries to open it
- * the with => open(2). This is a helper function for
- * => zzip_dir_open, => zzip_opendir and => zzip_open.
+ * This function will attach any of the .zip extensions then
+ * trying to open it the with => open(2). This is a helper
+ * function for => zzip_dir_open, => zzip_opendir and => zzip_open.
+ *
+ * This function returns a new system file handle or -1 on error.
+ * On error this function leaves the errno(3) of the underlying
+ * open(2) call on the last file.
*/
int
-__zzip_try_open(zzip_char_t* filename, int filemode,
- zzip_strings_t* ext, zzip_plugin_io_t io)
+__zzip_try_open(zzip_char_t * filename, int filemode,
+ zzip_strings_t * ext, zzip_plugin_io_t io)
{
auto char file[PATH_MAX];
int fd;
- zzip_size_t len = strlen (filename);
-
- if (len+4 >= PATH_MAX) return -1;
- memcpy(file, filename, len+1);
+ zzip_size_t len = strlen(filename);
+
+ if (len + 4 >= PATH_MAX)
+ { errno = ENAMETOOLONG; return -1; }
+ memcpy(file, filename, len + 1);
- if (!io) io = zzip_get_default_io();
- if (!ext) ext = zzip_get_default_ext();
+ if (! io)
+ io = zzip_get_default_io();
+ if (! ext)
+ ext = zzip_get_default_ext();
- for ( ; *ext ; ++ext)
+ for (; *ext; ++ext)
{
- strcpy (file+len, *ext);
+ strcpy(file + len, *ext);
fd = io->fd.open(file, filemode);
- if (fd != -1) return fd;
+ if (fd != -1)
+ return fd;
}
return -1;
-}
+}
/**
* Opens the zip-archive (if available).
- * the two ext_io arguments will default to use posix io and
+ * the two ext_io arguments will default to use posix io and
* a set of default fileext that can atleast add .zip ext itself.
*/
-ZZIP_DIR*
-zzip_dir_open(zzip_char_t* filename, zzip_error_t* e)
+ZZIP_DIR *
+zzip_dir_open(zzip_char_t * filename, zzip_error_t * e)
{
- return zzip_dir_open_ext_io (filename, e, 0, 0);
+ return zzip_dir_open_ext_io(filename, e, 0, 0);
}
/** => zzip_dir_open
- * this function uses explicit ext and io instead of the internal
+ * this function uses explicit ext and io instead of the internal
* defaults. Setting these to zero is equivalent to => zzip_dir_open
*/
-ZZIP_DIR*
-zzip_dir_open_ext_io(zzip_char_t* filename, zzip_error_t* e,
- zzip_strings_t* ext, zzip_plugin_io_t io)
+ZZIP_DIR *
+zzip_dir_open_ext_io(zzip_char_t * filename, zzip_error_t * e,
+ zzip_strings_t * ext, zzip_plugin_io_t io)
{
int fd;
- if (!io) io = zzip_get_default_io();
- if (!ext) ext = zzip_get_default_ext();
+ if (! io)
+ io = zzip_get_default_io();
+ if (! ext)
+ ext = zzip_get_default_ext();
- fd = io->fd.open(filename, O_RDONLY|O_BINARY);
- if (fd != -1)
- { return zzip_dir_fdopen_ext_io(fd, e, ext, io); }
- else
+ fd = io->fd.open(filename, O_RDONLY | O_BINARY);
+ if (fd != -1)
{
- fd = __zzip_try_open(filename, O_RDONLY|O_BINARY, ext, io);
- if (fd != -1)
- { return zzip_dir_fdopen_ext_io(fd, e, ext, io); }
- else
+ return zzip_dir_fdopen_ext_io(fd, e, ext, io);
+ } else
+ {
+ fd = __zzip_try_open(filename, O_RDONLY | O_BINARY, ext, io);
+ if (fd != -1)
+ {
+ return zzip_dir_fdopen_ext_io(fd, e, ext, io);
+ } else
{
- if (e) { *e = ZZIP_DIR_OPEN; }
- return 0;
+ if (e)
+ { *e = ZZIP_DIR_OPEN; }
+ return 0;
}
}
}
/** => zzip_dir_open
- * fills the dirent-argument with the values and
+ * fills the dirent-argument with the values and
* increments the read-pointer of the dir-argument.
- *
+ *
* returns 0 if there no entry (anymore).
*/
int
-zzip_dir_read(ZZIP_DIR * dir, ZZIP_DIRENT * d )
+zzip_dir_read(ZZIP_DIR * dir, ZZIP_DIRENT * d)
{
- if (! dir || ! dir->hdr || ! d) return 0;
+ if (! dir || ! dir->hdr || ! d)
+ return 0;
d->d_compr = dir->hdr->d_compr;
d->d_csize = dir->hdr->d_csize;
d->st_size = dir->hdr->d_usize;
- d->d_name = dir->hdr->d_name;
+ d->d_name = dir->hdr->d_name;
+
+ if (! dir->hdr->d_reclen)
+ {
+ dir->hdr = 0;
+ } else
+ {
+ dir->hdr = (struct zzip_dir_hdr *)
+ ((char *) dir->hdr + dir->hdr->d_reclen);
+ }
- if (! dir->hdr->d_reclen)
- { dir->hdr = 0; }
- else
- { dir->hdr = (struct zzip_dir_hdr *)((char *)dir->hdr + dir->hdr->d_reclen); }
-
return 1;
}
-/*
+/*
* Local variables:
* c-file-style: "stroustrup"
* End: