Use fseeko/ftello throughout, and use off_t to store file offsets. Fixes reading zip archives >2gb. --HG-- branch : HEAD
diff --git a/configure.ac b/configure.ac index 0a089b0..fc09dbd 100644 --- a/configure.ac +++ b/configure.ac
@@ -41,7 +41,7 @@ AM_PROG_LIBTOOL -AC_CHECK_FUNCS([fseeko MoveFileEx]) +AC_CHECK_FUNCS([fseeko ftello MoveFileEx]) AC_CHECK_FUNCS([mkstemp], [], [AC_LIBOBJ(mkstemp)]) AC_CHECK_HEADERS([unistd.h])
diff --git a/lib/zip_close.c b/lib/zip_close.c index 52e1037..75d20a7 100644 --- a/lib/zip_close.c +++ b/lib/zip_close.c
@@ -1,5 +1,5 @@ /* - $NiH: zip_close.c,v 1.64 2007/01/28 08:07:40 wiz Exp $ + $NiH: zip_close.c,v 1.65 2007/02/28 10:44:15 wiz Exp $ zip_close.c -- close zip archive and update changes Copyright (C) 1999, 2004, 2005, 2007 Dieter Baron and Thomas Klausner @@ -137,7 +137,7 @@ } else { /* copy existing directory entries */ - if (fseek(za->zp, za->cdir->entry[i].offset, SEEK_SET) != 0) { + if (fseeko(za->zp, za->cdir->entry[i].offset, SEEK_SET) != 0) { _zip_error_set(&za->error, ZIP_ER_SEEK, errno); error = 1; break; @@ -172,7 +172,7 @@ cd->entry[j].comment_len = za->entry[i].ch_comment_len; } - cd->entry[j].offset = ftell(out); + cd->entry[j].offset = ftello(out); if (ZIP_ENTRY_DATA_CHANGED(za->entry+i)) { if (add_data(za, i, &de, out) < 0) { @@ -275,7 +275,7 @@ return -1; } - offstart = ftell(ft); + offstart = ftello(ft); if (_zip_dirent_write(de, ft, 1, &za->error) < 0) return -1; @@ -294,9 +294,9 @@ return -1; } - offend = ftell(ft); + offend = ftello(ft); - if (fseek(ft, offstart, SEEK_SET) < 0) { + if (fseeko(ft, offstart, SEEK_SET) < 0) { _zip_error_set(&za->error, ZIP_ER_SEEK, errno); return -1; } @@ -310,7 +310,7 @@ if (_zip_dirent_write(de, ft, 1, &za->error) < 0) return -1; - if (fseek(ft, offend, SEEK_SET) < 0) { + if (fseeko(ft, offend, SEEK_SET) < 0) { _zip_error_set(&za->error, ZIP_ER_SEEK, errno); return -1; }
diff --git a/lib/zip_dirent.c b/lib/zip_dirent.c index 3735dff..b8258f1 100644 --- a/lib/zip_dirent.c +++ b/lib/zip_dirent.c
@@ -1,5 +1,5 @@ /* - $NiH: zip_dirent.c,v 1.9 2006/04/23 14:51:45 wiz Exp $ + $NiH: zip_dirent.c,v 1.10 2007/03/03 13:48:08 wiz Exp $ zip_dirent.c -- read directory entry (local or central), clean dirent Copyright (C) 1999, 2003, 2004, 2005 Dieter Baron and Thomas Klausner @@ -105,14 +105,14 @@ { int i; - cd->offset = ftell(fp); + cd->offset = ftello(fp); for (i=0; i<cd->nentry; i++) { if (_zip_dirent_write(cd->entry+i, fp, 0, error) != 0) return -1; } - cd->size = ftell(fp) - cd->offset; + cd->size = ftello(fp) - cd->offset; /* clearerr(fp); */ fwrite(EOCD_MAGIC, 1, 4, fp);
diff --git a/lib/zip_file_get_offset.c b/lib/zip_file_get_offset.c index 606b5e0..f0f4f3f 100644 --- a/lib/zip_file_get_offset.c +++ b/lib/zip_file_get_offset.c
@@ -1,5 +1,5 @@ /* - $NiH: zip_file_get_offset.c,v 1.3 2004/11/17 21:55:11 wiz Exp $ + $NiH: zip_file_get_offset.c,v 1.4 2006/04/23 14:51:45 wiz Exp $ zip_file_get_offset.c -- get offset of file data in archive. Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner @@ -61,7 +61,7 @@ offset = za->cdir->entry[idx].offset; - if (fseek(za->zp, offset, SEEK_SET) != 0) { + if (fseeko(za->zp, offset, SEEK_SET) != 0) { _zip_error_set(&za->error, ZIP_ER_SEEK, errno); return 0; }
diff --git a/lib/zip_fopen_index.c b/lib/zip_fopen_index.c index f77c9ee..4a49566 100644 --- a/lib/zip_fopen_index.c +++ b/lib/zip_fopen_index.c
@@ -1,5 +1,5 @@ /* - $NiH: zip_fopen_index.c,v 1.23 2005/01/17 10:45:20 dillo Exp $ + $NiH: zip_fopen_index.c,v 1.24 2005/05/20 21:54:53 wiz Exp $ zip_fopen_index.c -- open file in zip archive for reading by index Copyright (C) 1999, 2004, 2005 Dieter Baron and Thomas Klausner @@ -152,7 +152,7 @@ if ((zf->flags & ZIP_ZF_EOF) || zf->cbytes_left <= 0 || buflen <= 0) return 0; - if (fseek(zf->za->zp, zf->fpos, SEEK_SET) < 0) { + if (fseeko(zf->za->zp, zf->fpos, SEEK_SET) < 0) { _zip_error_set(&zf->error, ZIP_ER_SEEK, errno); return -1; }
diff --git a/lib/zip_open.c b/lib/zip_open.c index 46b68a3..6a69036 100644 --- a/lib/zip_open.c +++ b/lib/zip_open.c
@@ -1,5 +1,5 @@ /* - $NiH: zip_open.c,v 1.41 2007/02/28 09:29:27 wiz Exp $ + $NiH: zip_open.c,v 1.42 2007/02/28 18:08:39 wiz Exp $ zip_open.c -- open zip archive Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner @@ -47,7 +47,7 @@ static void set_error(int *, struct zip_error *, int); static struct zip *_zip_allocate_new(const char *, int *); static int _zip_checkcons(FILE *, struct zip_cdir *, struct zip_error *); -static struct zip_cdir *_zip_find_central_dir(FILE *, int, int *, long); +static struct zip_cdir *_zip_find_central_dir(FILE *, int, int *, off_t); static int _zip_file_exists(const char *, int, int *); static int _zip_headercomp(struct zip_dirent *, int, struct zip_dirent *, int); @@ -65,8 +65,8 @@ struct zip *za; struct zip_cdir *cdir; int i; - long len; - + off_t len; + switch (_zip_file_exists(fn, flags, zep)) { case -1: return NULL; @@ -81,8 +81,8 @@ return NULL; } - fseek(fp, 0, SEEK_END); - len = ftell(fp); + fseeko(fp, 0, SEEK_END); + len = ftello(fp); /* treat empty files as empty archives */ if (len == 0) { @@ -214,10 +214,10 @@ /* go to start of cdir and read it entry by entry */ bufp = NULL; clearerr(fp); - fseek(fp, cd->offset, SEEK_SET); + fseeko(fp, cd->offset, SEEK_SET); /* possible consistency check: cd->offset = len-(cd->size+cd->comment_len+EOCDLEN) ? */ - if (ferror(fp) || ((unsigned long)ftell(fp) != cd->offset)) { + if (ferror(fp) || ((unsigned long)ftello(fp) != cd->offset)) { /* seek error or offset of cdir wrong */ if (ferror(fp)) _zip_error_set(error, ZIP_ER_SEEK, errno); @@ -279,7 +279,7 @@ return -1; } - if (fseek(fp, cd->entry[i].offset, SEEK_SET) != 0) { + if (fseeko(fp, cd->entry[i].offset, SEEK_SET) != 0) { _zip_error_set(error, ZIP_ER_SEEK, 0); return -1; } @@ -422,14 +422,14 @@ static struct zip_cdir * -_zip_find_central_dir(FILE *fp, int flags, int *zep, long len) +_zip_find_central_dir(FILE *fp, int flags, int *zep, off_t len) { struct zip_cdir *cdir, *cdirnew; unsigned char *buf, *match; int a, best, buflen, i; struct zip_error zerr; - i = fseek(fp, -(len < CDBUFSIZE ? len : CDBUFSIZE), SEEK_END); + i = fseeko(fp, -(len < CDBUFSIZE ? len : CDBUFSIZE), SEEK_END); if (i == -1 && errno != EFBIG) { /* seek before start of file on my machine */ set_error(zep, NULL, ZIP_ER_SEEK);
diff --git a/lib/zipint.h b/lib/zipint.h index 7ca3f46..e4b1e2c 100644 --- a/lib/zipint.h +++ b/lib/zipint.h
@@ -2,7 +2,7 @@ #define _HAD_ZIPINT_H /* - $NiH: zipint.h,v 1.48 2006/04/24 14:04:19 dillo Exp $ + $NiH: zipint.h,v 1.50 2006/10/04 15:21:09 dillo Exp $ zipint.h -- internal declarations. Copyright (C) 1999-2006 Dieter Baron and Thomas Klausner @@ -49,6 +49,9 @@ #ifndef HAVE_FSEEKO #define fseeko(s, o, w) (fseek((s), (long int)(o), (w))) #endif +#ifndef HAVE_FTELLO +#define ftello(s) ((long)ftell((s))) +#endif @@ -117,7 +120,7 @@ int flags; /* -1: eof, >0: error */ int method; /* compression method */ - long fpos; /* position within zip file (fread/fwrite) */ + off_t fpos; /* position within zip file (fread/fwrite) */ unsigned long bytes_left; /* number of bytes left to read */ unsigned long cbytes_left; /* number of bytes of compressed data left */