git-svn-id: file:///var/lib/svn/clamav-devel/trunk/clamav-devel@16 77e5149b-7576-45b1-b177-96237e5ba77b
Tomasz Kojm authored on 2003/08/04 07:25:30... | ... |
@@ -68,7 +68,7 @@ dnl there is now a CREATE_PREFIX_TARGET_H in this file as a shorthand for |
68 | 68 |
dnl PREFIX_CONFIG_H from a target.h file, however w/o the target.h ever created |
69 | 69 |
dnl (the prefix is a bit different, since we add an extra -target- and -host-) |
70 | 70 |
dnl |
71 |
-dnl @version: $Id: acinclude.m4,v 1.2 2003/08/02 22:37:52 kojm Exp $ |
|
71 |
+dnl @version: $Id: acinclude.m4,v 1.3 2003/08/03 22:25:30 kojm Exp $ |
|
72 | 72 |
dnl @author Guido Draheim <guidod@gmx.de> STATUS: used often |
73 | 73 |
|
74 | 74 |
AC_DEFUN([AC_CREATE_TARGET_H], |
... | ... |
@@ -4110,7 +4110,7 @@ dnl AC_COMPILE_CHECK_SIZEOF(ptrdiff_t, $headers) |
4110 | 4110 |
dnl AC_COMPILE_CHECK_SIZEOF(off_t, $headers) |
4111 | 4111 |
dnl |
4112 | 4112 |
dnl @author Kaveh Ghazi <ghazi@caip.rutgers.edu> |
4113 |
-dnl @version $Id: acinclude.m4,v 1.2 2003/08/02 22:37:52 kojm Exp $ |
|
4113 |
+dnl @version $Id: acinclude.m4,v 1.3 2003/08/03 22:25:30 kojm Exp $ |
|
4114 | 4114 |
dnl |
4115 | 4115 |
AC_DEFUN([AC_COMPILE_CHECK_SIZEOF], |
4116 | 4116 |
[changequote(<<, >>)dnl |
... | ... |
@@ -81,7 +81,7 @@ dnl there is now a CREATE_PREFIX_TARGET_H in this file as a shorthand for |
81 | 81 |
dnl PREFIX_CONFIG_H from a target.h file, however w/o the target.h ever created |
82 | 82 |
dnl (the prefix is a bit different, since we add an extra -target- and -host-) |
83 | 83 |
dnl |
84 |
-dnl @version: $Id: aclocal.m4,v 1.2 2003/08/02 22:37:52 kojm Exp $ |
|
84 |
+dnl @version: $Id: aclocal.m4,v 1.3 2003/08/03 22:25:30 kojm Exp $ |
|
85 | 85 |
dnl @author Guido Draheim <guidod@gmx.de> STATUS: used often |
86 | 86 |
|
87 | 87 |
AC_DEFUN([AC_CREATE_TARGET_H], |
... | ... |
@@ -4041,7 +4041,7 @@ dnl AC_COMPILE_CHECK_SIZEOF(ptrdiff_t, $headers) |
4041 | 4041 |
dnl AC_COMPILE_CHECK_SIZEOF(off_t, $headers) |
4042 | 4042 |
dnl |
4043 | 4043 |
dnl @author Kaveh Ghazi <ghazi@caip.rutgers.edu> |
4044 |
-dnl @version $Id: aclocal.m4,v 1.2 2003/08/02 22:37:52 kojm Exp $ |
|
4044 |
+dnl @version $Id: aclocal.m4,v 1.3 2003/08/03 22:25:30 kojm Exp $ |
|
4045 | 4045 |
dnl |
4046 | 4046 |
AC_DEFUN([AC_COMPILE_CHECK_SIZEOF], |
4047 | 4047 |
[changequote(<<, >>)dnl |
... | ... |
@@ -2,7 +2,7 @@ |
2 | 2 |
* Author: |
3 | 3 |
* Guido Draheim <guidod@gmx.de> |
4 | 4 |
* |
5 |
- * Copyright (c) 2001 Guido Draheim |
|
5 |
+ * Copyright (c) 2001,2002,2003 Guido Draheim |
|
6 | 6 |
* All rights reserved, |
7 | 7 |
* use under the restrictions of the |
8 | 8 |
* Lesser GNU General Public License |
... | ... |
@@ -53,15 +53,34 @@ |
53 | 53 |
#define _zzip_inline inline |
54 | 54 |
#endif |
55 | 55 |
#endif |
56 |
+#ifndef _zzip_size_t |
|
57 |
+#ifdef ZZIP_size_t |
|
58 |
+#define _zzip_size_t ZZIP_size_t |
|
59 |
+#else |
|
60 |
+#define _zzip_size_t size_t |
|
61 |
+#endif |
|
62 |
+#endif |
|
63 |
+#ifndef _zzip_ssize_t |
|
64 |
+#ifdef ZZIP_ssize_t |
|
65 |
+#define _zzip_ssize_t ZZIP_ssize_t |
|
66 |
+#else |
|
67 |
+#define _zzip_ssize_t ssize_t |
|
68 |
+#endif |
|
69 |
+#endif |
|
56 | 70 |
|
57 | 71 |
/* whether this library shall use a 64bit off_t largefile variant in 64on32: */ |
58 | 72 |
/* (some exported names must be renamed to avoid bad calls after linking) */ |
59 |
-#if defined ZZIP_LARGEFILE_SENSITIVE && _FILE_OFFSET_BITS+0 == 64 |
|
60 |
-#define ZZIP_LARGEFILE_RENAME |
|
61 |
-#elif defined _LARGE_FILES /* on AIX */ |
|
62 |
-#define ZZIP_LARGEFILE_RENAME |
|
73 |
+#if defined ZZIP_LARGEFILE_SENSITIVE |
|
74 |
+# if _FILE_OFFSET_BITS+0 == 64 |
|
75 |
+# define ZZIP_LARGEFILE_RENAME |
|
76 |
+# elif defined _LARGE_FILES /* used on older AIX to get at 64bit off_t */ |
|
77 |
+# define ZZIP_LARGEFILE_RENAME |
|
78 |
+# elif defined _ZZIP_LARGEFILE /* or simply use this one for zzip64 runs */ |
|
79 |
+# define ZZIP_LARGEFILE_RENAME |
|
80 |
+# endif |
|
63 | 81 |
#endif |
64 |
-/* if some were forgotten but required to have 64bit off_t largefile.. */ |
|
82 |
+ |
|
83 |
+/* if the environment did not setup these for 64bit off_t largefile... */ |
|
65 | 84 |
#ifdef ZZIP_LARGEFILE_RENAME |
66 | 85 |
# ifndef _FILE_OFFSET_BITS |
67 | 86 |
# ifdef ZZIP__FILE_OFFSET_BITS /* == 64 */ |
... | ... |
@@ -70,7 +89,12 @@ |
70 | 70 |
# endif |
71 | 71 |
# ifndef _LARGE_FILES |
72 | 72 |
# ifdef ZZIP__LARGE_FILES /* == 1 */ |
73 |
-# define _LARGE_FILES 1 |
|
73 |
+# define _LARGE_FILES ZZIP__LARGE_FILES |
|
74 |
+# endif |
|
75 |
+# endif |
|
76 |
+# ifndef _LARGEFILE_SOURCE |
|
77 |
+# ifdef ZZIP__LARGEFILE_SOURCE /* == 1 */ |
|
78 |
+# define _LARGEFILE_SOURCE ZZIP__LARGEFILE_SOURCE |
|
74 | 79 |
# endif |
75 | 80 |
# endif |
76 | 81 |
#endif |
... | ... |
@@ -141,6 +165,11 @@ |
141 | 141 |
#define __attribute__(X) |
142 | 142 |
#endif |
143 | 143 |
|
144 |
+#if defined ZZIP_EXPORTS || defined ZZIPLIB_EXPORTS |
|
145 |
+# undef ZZIP_DLL |
|
146 |
+#define ZZIP_DLL 1 |
|
147 |
+#endif |
|
148 |
+ |
|
144 | 149 |
/* based on zconf.h : */ |
145 | 150 |
/* compile with -DZZIP_DLL for Windows DLL support */ |
146 | 151 |
#if defined ZZIP_DLL |
... | ... |
@@ -1,4 +1,3 @@ |
1 |
-#define USE_DIRENT 0 |
|
2 | 1 |
/* |
3 | 2 |
* Author: |
4 | 3 |
* Guido Draheim <guidod@gmx.de> |
... | ... |
@@ -39,6 +38,8 @@ |
39 | 39 |
# endif |
40 | 40 |
#endif |
41 | 41 |
|
42 |
+#define USE_DIRENT 0 |
|
43 |
+ |
|
42 | 44 |
/** |
43 | 45 |
* This function is the equivalent of a => rewinddir(2) for a realdir or |
44 | 46 |
* the zipfile in place of a directory. The ZZIP_DIR handle returned from |
... | ... |
@@ -88,17 +88,14 @@ zzip_file_saveoffset(ZZIP_FILE * fp) |
88 | 88 |
return 0; |
89 | 89 |
} |
90 | 90 |
|
91 |
- |
|
92 |
- |
|
93 |
-# ifndef ZZIP_CHECK_BACKSLASH_DIRSEPARATOR |
|
94 |
-# define ZZIP_CHECK_BACKSLASH_DIRSEPARATOR 0 |
|
91 |
+# ifndef ZZIP_CHECK_BACKSLASH_DIRSEPARATOR /* NOTE: also default */ |
|
92 |
+# define ZZIP_CHECK_BACKSLASH_DIRSEPARATOR 0 /* to "NO" on win32 ! */ |
|
95 | 93 |
# endif |
96 | 94 |
|
97 | 95 |
# if !defined strcasecmp && !defined ZZIP_HAVE_STRCASECMP |
98 | 96 |
# define ZZIP_CHECK_BACKSLASH_DIRSEPARATOR 1 |
99 | 97 |
# endif |
100 | 98 |
|
101 |
- |
|
102 | 99 |
#if ! ZZIP_CHECK_BACKSLASH_DIRSEPARATOR+0 |
103 | 100 |
#define dirsep_strrchr(N,C) strrchr(N,C) |
104 | 101 |
#define dirsep_casecmp strcasecmp |
... | ... |
@@ -222,11 +219,11 @@ zzip_file_open(ZZIP_DIR * dir, zzip_char_t* name, int o_mode) |
222 | 222 |
|
223 | 223 |
{ /* skip local header - should test tons of other info, |
224 | 224 |
* but trust that those are correct */ |
225 |
- int dataoff; |
|
225 |
+ zzip_ssize_t dataoff; |
|
226 | 226 |
struct zzip_file_header * p = (void*) fp->buf32k; |
227 | 227 |
|
228 | 228 |
dataoff = dir->io->read(dir->fd, (void*)p, sizeof(*p)); |
229 |
- if (dataoff < (int) sizeof(*p)) |
|
229 |
+ if (dataoff < (zzip_ssize_t)sizeof(*p)) |
|
230 | 230 |
{ err = ZZIP_DIR_READ; goto error; } |
231 | 231 |
if (! ZZIP_FILE_HEADER_CHECKMAGIC(p)) /* PK\3\4 */ |
232 | 232 |
{ err = ZZIP_CORRUPTED; goto error; } |
... | ... |
@@ -323,12 +320,12 @@ zzip_close(ZZIP_FILE* fp) |
323 | 323 |
* required just that but the latest zlib would work just fine with |
324 | 324 |
* a smaller buffer. |
325 | 325 |
*/ |
326 |
-int |
|
327 |
-zzip_file_read(ZZIP_FILE * fp, char * buf, int len) |
|
326 |
+zzip_ssize_t |
|
327 |
+zzip_file_read(ZZIP_FILE * fp, char * buf, zzip_size_t len) |
|
328 | 328 |
{ |
329 | 329 |
ZZIP_DIR * dir; |
330 |
- int l; |
|
331 |
- int rv; |
|
330 |
+ zzip_size_t l; |
|
331 |
+ zzip_ssize_t rv; |
|
332 | 332 |
|
333 | 333 |
if (! fp || ! fp->dir) return 0; |
334 | 334 |
|
... | ... |
@@ -358,14 +355,15 @@ zzip_file_read(ZZIP_FILE * fp, char * buf, int len) |
358 | 358 |
|
359 | 359 |
do { |
360 | 360 |
int err; |
361 |
- int startlen; |
|
361 |
+ zzip_size_t startlen; |
|
362 | 362 |
|
363 | 363 |
if (fp->crestlen > 0 && fp->d_stream.avail_in == 0) |
364 | 364 |
{ |
365 |
- int cl = fp->crestlen > ZZIP_32K ? ZZIP_32K : fp->crestlen; |
|
366 |
- /* int cl = fp->crestlen > 128? 128: fp->crestlen; */ |
|
365 |
+ zzip_size_t cl = ( fp->crestlen < ZZIP_32K ? |
|
366 |
+ fp->crestlen : ZZIP_32K ); |
|
367 |
+ /* zzip_size_t cl = fp->crestlen > 128 ? 128 : fp->crestlen; */ |
|
367 | 368 |
|
368 |
- int i = fp->io->read(dir->fd, fp->buf32k, cl); |
|
369 |
+ zzip_ssize_t i = fp->io->read(dir->fd, fp->buf32k, cl); |
|
369 | 370 |
if (i <= 0) |
370 | 371 |
{ |
371 | 372 |
dir->errcode = ZZIP_DIR_READ; /* or ZZIP_DIR_READ_EOF ? */ |
... | ... |
@@ -412,14 +410,14 @@ zzip_file_read(ZZIP_FILE * fp, char * buf, int len) |
412 | 412 |
* perform a normal => read(2)-call, otherwise => zzip_file_read is called |
413 | 413 |
* to decompress the data stream and any error is mapped to => errno(3). |
414 | 414 |
*/ |
415 |
-int |
|
416 |
-zzip_read(ZZIP_FILE * fp, char * buf, int len) |
|
415 |
+zzip_ssize_t |
|
416 |
+zzip_read(ZZIP_FILE * fp, char * buf, zzip_size_t len) |
|
417 | 417 |
{ |
418 | 418 |
if (! fp) return 0; |
419 | 419 |
if (! fp->dir) |
420 | 420 |
{ return fp->io->read(fp->fd, buf, len); } /* stat fd */ |
421 | 421 |
else |
422 |
- { register int v; |
|
422 |
+ { register zzip_ssize_t v; |
|
423 | 423 |
v = zzip_file_read(fp, buf, len); |
424 | 424 |
if (v == -1) { errno = zzip_errno(fp->dir->errcode); } |
425 | 425 |
return v; |
... | ... |
@@ -428,8 +426,8 @@ zzip_read(ZZIP_FILE * fp, char * buf, int len) |
428 | 428 |
|
429 | 429 |
/** => zzip_read |
430 | 430 |
*/ |
431 |
-int |
|
432 |
-zzip_fread(void *ptr, int size, int nmemb, ZZIP_FILE *file) |
|
431 |
+zzip_size_t |
|
432 |
+zzip_fread(void *ptr, zzip_size_t size, zzip_size_t nmemb, ZZIP_FILE *file) |
|
433 | 433 |
{ |
434 | 434 |
if (! size) size=1; |
435 | 435 |
return zzip_read (file, ptr, size*nmemb)/size; |
... | ... |
@@ -714,7 +712,7 @@ zzip_open_shared_io (ZZIP_FILE* stream, |
714 | 714 |
/* see if we can share the same zip directory */ |
715 | 715 |
if (stream && stream->dir && stream->dir->realname) |
716 | 716 |
{ |
717 |
- int len = strlen (stream->dir->realname); |
|
717 |
+ zzip_size_t len = strlen (stream->dir->realname); |
|
718 | 718 |
if (! memcmp (filename, stream->dir->realname, len) && |
719 | 719 |
filename[len] == '/' && filename[len+1]) |
720 | 720 |
{ |
... | ... |
@@ -864,10 +862,10 @@ zzip_rewind(ZZIP_FILE *fp) |
864 | 864 |
* how gzio implements it, so I'm not sure there is a better way |
865 | 865 |
* without using the internals of the algorithm. |
866 | 866 |
*/ |
867 |
-int |
|
868 |
-zzip_seek(ZZIP_FILE * fp, int offset, int whence) |
|
867 |
+zzip_off_t |
|
868 |
+zzip_seek(ZZIP_FILE * fp, zzip_off_t offset, int whence) |
|
869 | 869 |
{ |
870 |
- int cur_pos, rel_ofs, read_size, ofs; |
|
870 |
+ zzip_off_t cur_pos, rel_ofs, read_size, ofs; |
|
871 | 871 |
ZZIP_DIR *dir; |
872 | 872 |
|
873 | 873 |
if (! fp) |
... | ... |
@@ -875,7 +873,7 @@ zzip_seek(ZZIP_FILE * fp, int offset, int whence) |
875 | 875 |
|
876 | 876 |
if (! fp->dir) |
877 | 877 |
{ /* stat fd */ |
878 |
- return fp->io->seeks(fp->fd,offset,whence); |
|
878 |
+ return fp->io->seeks(fp->fd, offset, whence); |
|
879 | 879 |
} |
880 | 880 |
|
881 | 881 |
cur_pos = zzip_tell(fp); |
... | ... |
@@ -914,7 +912,7 @@ zzip_seek(ZZIP_FILE * fp, int offset, int whence) |
914 | 914 |
if (read_size < 0) /* bad offset, before beginning of file */ |
915 | 915 |
return -1; |
916 | 916 |
|
917 |
- if (read_size + cur_pos > fp->usize) /* bad offset, past EOF */ |
|
917 |
+ if (read_size + cur_pos > (zzip_off_t)fp->usize) /* bad offset, past EOF */ |
|
918 | 918 |
return -1; |
919 | 919 |
|
920 | 920 |
if (read_size == 0) /* nothing to read */ |
... | ... |
@@ -953,10 +951,10 @@ zzip_seek(ZZIP_FILE * fp, int offset, int whence) |
953 | 953 |
|
954 | 954 |
while (read_size > 0) |
955 | 955 |
{ |
956 |
- int size = ZZIP_32K; |
|
957 |
- if (read_size < ZZIP_32K) size = (int)read_size; |
|
956 |
+ zzip_off_t size = ZZIP_32K; |
|
957 |
+ if (read_size < size/*32K*/) size = read_size; |
|
958 | 958 |
|
959 |
- size = zzip_file_read(fp, buf, size); |
|
959 |
+ size = zzip_file_read(fp, buf, (zzip_size_t)size); |
|
960 | 960 |
if (size <= 0) { free(buf); return -1; } |
961 | 961 |
|
962 | 962 |
read_size -= size; |
... | ... |
@@ -979,7 +977,7 @@ zzip_seek(ZZIP_FILE * fp, int offset, int whence) |
979 | 979 |
* calculated from the amount of data left and the total uncompressed |
980 | 980 |
* size; |
981 | 981 |
*/ |
982 |
-int |
|
982 |
+zzip_off_t |
|
983 | 983 |
zzip_tell(ZZIP_FILE * fp) |
984 | 984 |
{ |
985 | 985 |
if (! fp) |
... | ... |
@@ -65,10 +65,10 @@ struct zzip_file |
65 | 65 |
struct zzip_dir* dir; |
66 | 66 |
int fd; |
67 | 67 |
int method; |
68 |
- int restlen; |
|
69 |
- int crestlen; |
|
70 |
- int usize; |
|
71 |
- int csize; |
|
68 |
+ zzip_size_t restlen; |
|
69 |
+ zzip_size_t crestlen; |
|
70 |
+ zzip_size_t usize; |
|
71 |
+ zzip_size_t csize; |
|
72 | 72 |
/* added dataoffset member - data offset from start of zipfile*/ |
73 | 73 |
zzip_off_t dataoffset; |
74 | 74 |
char* buf32k; |
... | ... |
@@ -24,8 +24,11 @@ |
24 | 24 |
#include <sys/stat.h> |
25 | 25 |
#endif |
26 | 26 |
|
27 |
-//#include "__mmap.h" |
|
28 |
-//#include "__debug.h" |
|
27 |
+ |
|
28 |
+#define __sizeof(X) ((zzip_ssize_t)(sizeof(X))) |
|
29 |
+ |
|
30 |
+/* per default, we use a little hack to correct bad z_rootseek parts */ |
|
31 |
+#define ZZIP_CORRECT_ROOTSEEK 1 |
|
29 | 32 |
|
30 | 33 |
/* ------------------------- fetch helpers --------------------------------- */ |
31 | 34 |
|
... | ... |
@@ -47,6 +50,86 @@ uint16_t __zzip_get16(unsigned char * s) |
47 | 47 |
return ((uint16_t)s[1] << 8) | (uint16_t)s[0]; |
48 | 48 |
} |
49 | 49 |
|
50 |
+/* --------------------------- internals -------------------------------- */ |
|
51 |
+/* internal functions of zziplib, avoid at all cost, changes w/o warning. |
|
52 |
+ * we do export them for debugging purpose and special external tools |
|
53 |
+ * which know what they do and which can adapt from version to version |
|
54 |
+ */ |
|
55 |
+ |
|
56 |
+int __zzip_find_disk_trailer( int fd, zzip_off_t filesize, |
|
57 |
+ struct zzip_disk_trailer * trailer, |
|
58 |
+ zzip_plugin_io_t io); |
|
59 |
+int __zzip_parse_root_directory( int fd, |
|
60 |
+ struct zzip_disk_trailer * trailer, |
|
61 |
+ struct zzip_dir_hdr ** hdr_return, |
|
62 |
+ zzip_plugin_io_t io); |
|
63 |
+ |
|
64 |
+_zzip_inline char* __zzip_aligned4(char* p); |
|
65 |
+ |
|
66 |
+/* ------------------------ harden routines ------------------------------ */ |
|
67 |
+ |
|
68 |
+#ifdef ZZIP_HARDEN |
|
69 |
+/* |
|
70 |
+ * check for inconsistent values in trailer and prefer lower seek value |
|
71 |
+ * - we fix values assuming the root directory was written at the end |
|
72 |
+ * and it is just before the zip trailer. Therefore, ... |
|
73 |
+ */ |
|
74 |
+_zzip_inline static void __fixup_rootseek( |
|
75 |
+ zzip_off_t offset_of_trailer, |
|
76 |
+ struct zzip_disk_trailer* trailer) |
|
77 |
+{ |
|
78 |
+ if ( (zzip_off_t) ZZIP_GET32(trailer->z_rootseek) > |
|
79 |
+ offset_of_trailer - (zzip_off_t) ZZIP_GET32(trailer->z_rootsize) && |
|
80 |
+ offset_of_trailer > (zzip_off_t) ZZIP_GET32(trailer->z_rootsize)) |
|
81 |
+ { |
|
82 |
+ register zzip_off_t offset; |
|
83 |
+ offset = offset_of_trailer - ZZIP_GET32(trailer->z_rootsize); |
|
84 |
+ trailer->z_rootseek[0] = offset & 0xff; |
|
85 |
+ trailer->z_rootseek[1] = offset >> 8 & 0xff; |
|
86 |
+ trailer->z_rootseek[2] = offset >> 16 & 0xff; |
|
87 |
+ trailer->z_rootseek[3] = offset >> 24 & 0xff; |
|
88 |
+ } |
|
89 |
+} |
|
90 |
+#define __correct_rootseek(A,B,C) |
|
91 |
+ |
|
92 |
+#elif defined ZZIP_CORRECT_ROOTSEEK |
|
93 |
+/* store the seekvalue of the trailer into the "z_magic" field and with |
|
94 |
+ * a 64bit off_t we overwrite z_disk/z_finaldisk as well. If you change |
|
95 |
+ * anything in zziplib or dump the trailer structure then watch out that |
|
96 |
+ * these are still unused, so that this code may still (ab)use those. */ |
|
97 |
+#define __fixup_rootseek(_offset_of_trailer, _trailer) \ |
|
98 |
+ *(zzip_off_t*)_trailer = _offset_of_trailer; |
|
99 |
+#define __correct_rootseek( _u_rootseek, _u_rootsize, _trailer) \ |
|
100 |
+ if (_u_rootseek > *(zzip_off_t*)_trailer - _u_rootsize) \ |
|
101 |
+ _u_rootseek = *(zzip_off_t*)_trailer - _u_rootsize; |
|
102 |
+#else |
|
103 |
+#define __fixup_rootseek(A,B) |
|
104 |
+#define __correct_rootseek(A,B,C) |
|
105 |
+#endif |
|
106 |
+ |
|
107 |
+ |
|
108 |
+#ifdef DEBUG |
|
109 |
+_zzip_inline static void __debug_dir_hdr (struct zzip_dir_hdr* hdr) |
|
110 |
+{ |
|
111 |
+ if (sizeof(struct zzip_dir_hdr) > sizeof(struct zzip_root_dirent)) |
|
112 |
+ { WARN1("internal sizeof-mismatch may break wreakage"); } |
|
113 |
+ /* the internal directory structure is never bigger than the |
|
114 |
+ * external zip central directory space had been beforehand |
|
115 |
+ * (as long as the following assertion holds...) |
|
116 |
+ */ |
|
117 |
+ |
|
118 |
+ if (((unsigned)hdr)&3) |
|
119 |
+ { NOTE1("this machine's malloc(3) returns sth. not u32-aligned"); } |
|
120 |
+ /* we assume that if this machine's malloc has returned a non-aligned |
|
121 |
+ * memory block, then it is actually safe to access misaligned data, and |
|
122 |
+ * since it does only affect the first hdr it should not even bring about |
|
123 |
+ * too much of that cpu's speed penalty |
|
124 |
+ */ |
|
125 |
+} |
|
126 |
+#else |
|
127 |
+#define __debug_dir_hdr(X) |
|
128 |
+#endif |
|
129 |
+ |
|
50 | 130 |
/* -------------------------- low-level interface -------------------------- */ |
51 | 131 |
|
52 | 132 |
#if defined BUFSIZ |
... | ... |
@@ -70,11 +153,7 @@ __zzip_find_disk_trailer(int fd, zzip_off_t filesize, |
70 | 70 |
struct zzip_disk_trailer * trailer, |
71 | 71 |
zzip_plugin_io_t io) |
72 | 72 |
{ |
73 |
-#ifdef DEBUG |
|
74 |
-#define return(val) { e=val; goto cleanup; } |
|
75 |
-#else |
|
76 | 73 |
#define return(val) { e=val; goto cleanup; } |
77 |
-#endif |
|
78 | 74 |
register int e; |
79 | 75 |
|
80 | 76 |
#ifndef _LOWSTK |
... | ... |
@@ -84,13 +163,13 @@ __zzip_find_disk_trailer(int fd, zzip_off_t filesize, |
84 | 84 |
char* buf = malloc(2*ZZIP_BUFSIZ); |
85 | 85 |
#endif |
86 | 86 |
zzip_off_t offset = 0; |
87 |
- size_t maplen = 0; |
|
87 |
+ zzip_off_t maplen = 0; /* mmap(),read(),getpagesize() use size_t !! */ |
|
88 | 88 |
char* fd_map = 0; |
89 | 89 |
|
90 | 90 |
if (!trailer) |
91 | 91 |
{ return(EINVAL); } |
92 | 92 |
|
93 |
- if (filesize < sizeof(struct zzip_disk_trailer)) |
|
93 |
+ if (filesize < __sizeof(struct zzip_disk_trailer)) |
|
94 | 94 |
{ return(ZZIP_DIR_TOO_SHORT); } |
95 | 95 |
|
96 | 96 |
if (!buf) |
... | ... |
@@ -99,8 +178,7 @@ __zzip_find_disk_trailer(int fd, zzip_off_t filesize, |
99 | 99 |
offset = filesize; /* a.k.a. old offset */ |
100 | 100 |
while(1) /* outer loop */ |
101 | 101 |
{ |
102 |
- register unsigned char* p; |
|
103 |
- register unsigned char* s; |
|
102 |
+ register unsigned char* mapped; |
|
104 | 103 |
|
105 | 104 |
if (offset <= 0) { return(ZZIP_DIR_EDH_MISSING); } |
106 | 105 |
|
... | ... |
@@ -128,35 +206,40 @@ __zzip_find_disk_trailer(int fd, zzip_off_t filesize, |
128 | 128 |
|
129 | 129 |
if (io->seeks(fd, offset, SEEK_SET) < 0) |
130 | 130 |
{ return(ZZIP_DIR_SEEK); } |
131 |
- if (io->read(fd, buf, maplen) < (long)maplen) |
|
131 |
+ if (io->read(fd, buf, (zzip_size_t)maplen) < (zzip_ssize_t)maplen) |
|
132 | 132 |
{ return(ZZIP_DIR_READ); } |
133 |
- p = buf; /* success */ |
|
133 |
+ mapped = buf; /* success */ |
|
134 | 134 |
|
135 | 135 |
|
136 |
- /* now, check for the trailer-magic, hopefully near the end of file */ |
|
137 |
- for (s = p + maplen-1; (s >= p); s--) |
|
138 |
- { |
|
139 |
- if (*s == 'P' |
|
140 |
- && p+maplen-1-s > sizeof(*trailer)-2 |
|
141 |
- && ZZIP_DISK_TRAILER_CHECKMAGIC(s)) |
|
142 |
- { |
|
143 |
- /* if the file-comment is not present, it happens |
|
144 |
- that the z_comment field often isn't either */ |
|
145 |
- if (p+maplen-1-s > sizeof(*trailer)) |
|
146 |
- { memcpy (trailer, s, sizeof(*trailer)); } |
|
147 |
- else |
|
148 |
- { |
|
149 |
- memcpy (trailer, s, sizeof(*trailer)-2); |
|
150 |
- trailer->z_comment[0] = 0; trailer->z_comment[1] = 0; |
|
151 |
- } |
|
152 |
- |
|
153 |
- { return(0); } |
|
154 |
- } |
|
136 |
+ {/* now, check for the trailer-magic, hopefully near the end of file */ |
|
137 |
+ register unsigned char* end = mapped + maplen; |
|
138 |
+ register unsigned char* tail; |
|
139 |
+ for (tail = end-1; (tail >= mapped); tail--) |
|
140 |
+ { |
|
141 |
+ if ((*tail == 'P') && /* quick pre-check for trailer magic */ |
|
142 |
+ end-tail >= __sizeof(*trailer)-2 && |
|
143 |
+ ZZIP_DISK_TRAILER_CHECKMAGIC(tail)) |
|
144 |
+ { |
|
145 |
+ /* if the file-comment is not present, it happens |
|
146 |
+ that the z_comment field often isn't either */ |
|
147 |
+ if (end-tail >= __sizeof(*trailer)) |
|
148 |
+ { |
|
149 |
+ memcpy (trailer, tail, sizeof(*trailer)); |
|
150 |
+ }else{ |
|
151 |
+ memcpy (trailer, tail, sizeof(*trailer)-2); |
|
152 |
+ trailer->z_comment[0] = 0; |
|
153 |
+ trailer->z_comment[1] = 0; |
|
154 |
+ } |
|
155 |
+ |
|
156 |
+ __fixup_rootseek (offset + tail-mapped, trailer); |
|
157 |
+ { return(0); } |
|
158 |
+ } |
|
159 |
+ } |
|
155 | 160 |
} |
156 | 161 |
|
157 | 162 |
} /*outer loop*/ |
158 | 163 |
|
159 |
- cleanup: |
|
164 |
+cleanup: |
|
160 | 165 |
# ifdef _LOWSTK |
161 | 166 |
free(buf); |
162 | 167 |
# endif |
... | ... |
@@ -174,8 +257,8 @@ __zzip_find_disk_trailer(int fd, zzip_off_t filesize, |
174 | 174 |
_zzip_inline char* __zzip_aligned4(char* p) |
175 | 175 |
{ |
176 | 176 |
#define aligned4 __zzip_aligned4 |
177 |
- p += ((long)p)&1; |
|
178 |
- p += ((long)p)&2; |
|
177 |
+ p += ((long)p)&1; /* warnings about truncation of a "pointer" */ |
|
178 |
+ p += ((long)p)&2; /* to a "long int" may be safely ignored :) */ |
|
179 | 179 |
return p; |
180 | 180 |
} |
181 | 181 |
|
... | ... |
@@ -196,34 +279,19 @@ __zzip_parse_root_directory(int fd, |
196 | 196 |
struct zzip_dir_hdr * hdr0; |
197 | 197 |
uint16_t * p_reclen = 0; |
198 | 198 |
short entries; |
199 |
- long offset; |
|
200 |
- char* fd_map = 0; |
|
199 |
+ long offset; /* offset from start of root directory */ |
|
200 |
+ char* fd_map = 0; |
|
201 | 201 |
int32_t fd_gap = 0; |
202 | 202 |
uint16_t u_entries = ZZIP_GET16(trailer->z_entries); |
203 | 203 |
uint32_t u_rootsize = ZZIP_GET32(trailer->z_rootsize); |
204 | 204 |
uint32_t u_rootseek = ZZIP_GET32(trailer->z_rootseek); |
205 |
+ __correct_rootseek (u_rootseek, u_rootsize, trailer); |
|
205 | 206 |
|
206 | 207 |
hdr0 = (struct zzip_dir_hdr*) malloc(u_rootsize); |
207 | 208 |
if (!hdr0) |
208 | 209 |
return ZZIP_DIRSIZE; |
209 |
- hdr = hdr0; |
|
210 |
+ hdr = hdr0; __debug_dir_hdr (hdr); |
|
210 | 211 |
|
211 |
-# ifdef DEBUG |
|
212 |
- if (sizeof(struct zzip_dir_hdr) > sizeof(struct zzip_root_dirent)) |
|
213 |
- { WARN1("internal sizeof-mismatch may break wreakage"); } |
|
214 |
- /* the internal directory structure is never bigger than the |
|
215 |
- * external zip central directory space had been beforehand |
|
216 |
- * (as long as the following assertion holds...) |
|
217 |
- */ |
|
218 |
- |
|
219 |
- if (((unsigned)hdr0)&3) |
|
220 |
- { NOTE1("this machine's malloc(3) returns sth. not u32-aligned"); } |
|
221 |
- /* we assume that if this machine's malloc has returned a non-aligned |
|
222 |
- * memory block, then it is actually safe to access misaligned data, and |
|
223 |
- * since it does only affect the first hdr it should not even bring about |
|
224 |
- * too much of that cpu's speed penalty |
|
225 |
- */ |
|
226 |
-# endif |
|
227 | 212 |
|
228 | 213 |
for (entries=u_entries, offset=0; entries > 0; entries--) |
229 | 214 |
{ |
... | ... |
@@ -236,11 +304,13 @@ __zzip_parse_root_directory(int fd, |
236 | 236 |
{ |
237 | 237 |
if (io->seeks(fd, u_rootseek+offset, SEEK_SET) < 0) |
238 | 238 |
return ZZIP_DIR_SEEK; |
239 |
- if (io->read(fd, &dirent, sizeof(dirent)) < sizeof(dirent)) |
|
239 |
+ if (io->read(fd, &dirent, sizeof(dirent)) < __sizeof(dirent)) |
|
240 | 240 |
return ZZIP_DIR_READ; |
241 | 241 |
d = &dirent; |
242 | 242 |
} |
243 | 243 |
|
244 |
+ if (offset+sizeof(*d) > u_rootsize) |
|
245 |
+ |
|
244 | 246 |
# if 0 && defined DEBUG |
245 | 247 |
zzip_debug_xbuf ((unsigned char*) d, sizeof(*d) + 8); |
246 | 248 |
# endif |
... | ... |
@@ -248,8 +318,7 @@ __zzip_parse_root_directory(int fd, |
248 | 248 |
u_extras = ZZIP_GET16(d->z_extras); |
249 | 249 |
u_comment = ZZIP_GET16(d->z_comment); |
250 | 250 |
u_namlen = ZZIP_GET16(d->z_namlen); |
251 |
- |
|
252 |
- |
|
251 |
+ |
|
253 | 252 |
/* writes over the read buffer, Since the structure where data is |
254 | 253 |
copied is smaller than the data in buffer this can be done. |
255 | 254 |
It is important that the order of setting the fields is considered |
... | ... |
@@ -264,10 +333,11 @@ __zzip_parse_root_directory(int fd, |
264 | 264 |
hdr->d_compr = (uint8_t)ZZIP_GET16(d->z_compr); |
265 | 265 |
if (hdr->d_compr > 255) hdr->d_compr = 255; |
266 | 266 |
|
267 |
- if (fd_map) |
|
268 |
- { memcpy(hdr->d_name, fd_map+fd_gap+offset+sizeof(*d), u_namlen); } |
|
269 |
- else |
|
270 |
- { io->read(fd, hdr->d_name, u_namlen); } |
|
267 |
+ if (offset+sizeof(*d) + u_namlen > u_rootsize) |
|
268 |
+ |
|
269 |
+ if (fd_map) |
|
270 |
+ { memcpy(hdr->d_name, fd_map+fd_gap+offset+sizeof(*d), u_namlen); } |
|
271 |
+ else { io->read(fd, hdr->d_name, u_namlen); } |
|
271 | 272 |
hdr->d_name[u_namlen] = '\0'; |
272 | 273 |
hdr->d_namlen = u_namlen; |
273 | 274 |
|
... | ... |
@@ -275,26 +345,25 @@ __zzip_parse_root_directory(int fd, |
275 | 275 |
offset += sizeof(*d) + u_namlen + u_extras + u_comment; |
276 | 276 |
|
277 | 277 |
if (offset > (long)u_rootsize) |
278 |
- break; |
|
279 | 278 |
|
279 |
+ |
|
280 | 280 |
p_reclen = &hdr->d_reclen; |
281 | 281 |
|
282 | 282 |
{ register char* p = (char*) hdr; |
283 | 283 |
register char* q = aligned4 (p + sizeof(*hdr) + u_namlen + 1); |
284 |
- *p_reclen = q - p; |
|
284 |
+ *p_reclen = (uint16_t)(q - p); |
|
285 | 285 |
hdr = (struct zzip_dir_hdr*) q; |
286 | 286 |
} |
287 | 287 |
}/*for*/ |
288 | 288 |
|
289 |
- if (!p_reclen) |
|
290 |
- return 0; /* 0 (sane) entries in zip directory... */ |
|
291 |
- |
|
292 |
- *p_reclen = 0; /* mark end of list */ |
|
293 |
- |
|
294 |
- if (hdr_return) |
|
295 |
- *hdr_return = hdr0; |
|
289 |
+ if (p_reclen) |
|
290 |
+ { |
|
291 |
+ *p_reclen = 0; /* mark end of list */ |
|
296 | 292 |
|
297 |
- return 0; |
|
293 |
+ if (hdr_return) |
|
294 |
+ *hdr_return = hdr0; |
|
295 |
+ } /* else zero (sane) entries */ |
|
296 |
+ return (entries ? ZZIP_CORRUPTED : 0); |
|
298 | 297 |
} |
299 | 298 |
|
300 | 299 |
/* ------------------------- high-level interface ------------------------- */ |
... | ... |
@@ -451,7 +520,6 @@ __zzip_dir_parse (ZZIP_DIR* dir) |
451 | 451 |
dir->io)) != 0) |
452 | 452 |
{ goto error; } |
453 | 453 |
|
454 |
- |
|
455 | 454 |
if ( (rv = __zzip_parse_root_directory(dir->fd, &trailer, &dir->hdr0, |
456 | 455 |
dir->io)) != 0) |
457 | 456 |
{ goto error; } |
... | ... |
@@ -470,7 +538,7 @@ __zzip_try_open(zzip_char_t* filename, int filemode, |
470 | 470 |
{ |
471 | 471 |
auto char file[PATH_MAX]; |
472 | 472 |
int fd; |
473 |
- int len = strlen (filename); |
|
473 |
+ zzip_size_t len = strlen (filename); |
|
474 | 474 |
|
475 | 475 |
if (len+4 >= PATH_MAX) return -1; |
476 | 476 |
memcpy(file, filename, len+1); |
... | ... |
@@ -75,6 +75,9 @@ ZZIP_DIR* |
75 | 75 |
zzip_dir_fdopen_ext_io(int fd, zzip_error_t * errorcode_p, |
76 | 76 |
zzip_strings_t* ext, const zzip_plugin_io_t io); |
77 | 77 |
|
78 |
+ZZIP_DIR* /*depracated*/ |
|
79 |
+zzip_dir_alloc_ext_io (zzip_strings_t* ext, const zzip_plugin_io_t io); |
|
80 |
+ |
|
78 | 81 |
/* get 16/32 bits from little-endian zip-file to host byteorder */ |
79 | 82 |
uint32_t __zzip_get32(unsigned char * s); |
80 | 83 |
uint16_t __zzip_get16(unsigned char * s); |
... | ... |
@@ -3,12 +3,17 @@ |
3 | 3 |
* Guido Draheim <guidod@gmx.de> |
4 | 4 |
* Tomi Ollila <Tomi.Ollila@iki.fi> |
5 | 5 |
* |
6 |
- * Copyright (c) 1999,2000,2001,2002 Guido Draheim |
|
6 |
+ * Copyright (c) 1999,2000,2001,2002,2003 Guido Draheim |
|
7 | 7 |
* All rights reserved, |
8 | 8 |
* usage allowed under the restrictions of the |
9 | 9 |
* Lesser GNU General Public License |
10 | 10 |
* note the additional license information |
11 | 11 |
* that can be found in COPYING.ZZIP |
12 |
+ * |
|
13 |
+ * if you see "unknown symbol" errors, check first that `-I ..` is part of |
|
14 |
+ * your compiler options - a special hint to VC/IDE users who tend to make up |
|
15 |
+ * their own workspace files. All includes look like #include <zzip|*.h>, so |
|
16 |
+ * you need to add an include path to the dir containing (!!) the ./zzip/ dir |
|
12 | 17 |
*/ |
13 | 18 |
|
14 | 19 |
#ifndef _ZZIP_ZZIP_H /* zziplib.h */ |
... | ... |
@@ -17,6 +22,8 @@ |
17 | 17 |
#include <zzip-conf.h> |
18 | 18 |
|
19 | 19 |
#include <fcntl.h> |
20 |
+#include <stddef.h> /* size_t and friends */ |
|
21 |
+/* msvc6 has neither ssize_t (we assume "int") nor off_t (assume "long") */ |
|
20 | 22 |
|
21 | 23 |
#ifdef __cplusplus |
22 | 24 |
extern "C" { |
... | ... |
@@ -72,6 +79,8 @@ typedef enum |
72 | 72 |
typedef char _zzip_const * _zzip_const zzip_strings_t; |
73 | 73 |
typedef char _zzip_const zzip_char_t; |
74 | 74 |
typedef _zzip_off_t zzip_off_t; |
75 |
+typedef _zzip_size_t zzip_size_t; |
|
76 |
+typedef _zzip_ssize_t zzip_ssize_t; |
|
75 | 77 |
typedef struct zzip_dir ZZIP_DIR; |
76 | 78 |
typedef struct zzip_file ZZIP_FILE; |
77 | 79 |
typedef struct zzip_dirent ZZIP_DIRENT; |
... | ... |
@@ -173,14 +182,14 @@ ZZIP_FILE * zzip_file_open(ZZIP_DIR * dir, zzip_char_t* name, int modes); |
173 | 173 |
_zzip_export |
174 | 174 |
int zzip_file_close(ZZIP_FILE * fp); |
175 | 175 |
_zzip_export |
176 |
-int zzip_file_read(ZZIP_FILE * fp, char* buf, int len); |
|
176 |
+zzip_ssize_t zzip_file_read(ZZIP_FILE * fp, char* buf, zzip_size_t len); |
|
177 | 177 |
|
178 | 178 |
_zzip_export |
179 | 179 |
ZZIP_FILE * zzip_open(zzip_char_t* name, int flags); |
180 | 180 |
_zzip_export |
181 | 181 |
int zzip_close(ZZIP_FILE * fp); |
182 | 182 |
_zzip_export |
183 |
-int zzip_read(ZZIP_FILE * fp, char * buf, int len); |
|
183 |
+zzip_ssize_t zzip_read(ZZIP_FILE * fp, char * buf, zzip_size_t len); |
|
184 | 184 |
|
185 | 185 |
|
186 | 186 |
_zzip_export |
... | ... |
@@ -188,7 +197,8 @@ ZZIP_FILE* zzip_freopen(zzip_char_t* name, zzip_char_t* mode, ZZIP_FILE*); |
188 | 188 |
_zzip_export |
189 | 189 |
ZZIP_FILE* zzip_fopen(zzip_char_t* name, zzip_char_t* mode); |
190 | 190 |
_zzip_export |
191 |
-int zzip_fread(void *ptr, int size, int nmemb, ZZIP_FILE *file); |
|
191 |
+zzip_size_t zzip_fread(void *ptr, zzip_size_t size, zzip_size_t nmemb, |
|
192 |
+ ZZIP_FILE * file); |
|
192 | 193 |
_zzip_export |
193 | 194 |
int zzip_fclose(ZZIP_FILE * fp); |
194 | 195 |
|
... | ... |
@@ -198,10 +208,9 @@ int zzip_fclose(ZZIP_FILE * fp); |
198 | 198 |
_zzip_export |
199 | 199 |
int zzip_rewind(ZZIP_FILE *fp); |
200 | 200 |
_zzip_export |
201 |
-int zzip_seek(ZZIP_FILE * fp, int offset, int |
|
202 |
- whence); |
|
201 |
+zzip_off_t zzip_seek(ZZIP_FILE * fp, zzip_off_t offset, int whence); |
|
203 | 202 |
_zzip_export |
204 |
-int zzip_tell(ZZIP_FILE * fp); |
|
203 |
+zzip_off_t zzip_tell(ZZIP_FILE * fp); |
|
205 | 204 |
|
206 | 205 |
|
207 | 206 |
/* |