Fix remaining llvm warnings.
diff --git a/TODO b/TODO index d8e124d..15b4a2c 100644 --- a/TODO +++ b/TODO
@@ -57,9 +57,7 @@ ! D check for off_t overflow ! D fix OpenSUSE i686 regression failures ! D readd zip_get_num_files man page -! D zip_file_extra_field_{delete,set}*: use dirent changes (create if necessary) ! WD check inconsistent file test case result -! fix extra_count_ignore_zip64.test * fix open_filename_duplicate_consistency.test to fail * split zip archive torrentzip state from user requested torrentzip state * check for limits imposed by format (central dir size, file size, extra fields, ...)
diff --git a/lib/zip_close.c b/lib/zip_close.c index 196c2be..9bd53f6 100644 --- a/lib/zip_close.c +++ b/lib/zip_close.c
@@ -224,7 +224,7 @@ error = 1; break; } - if ((fseek(za->zp, offset, SEEK_SET) < 0)) { + if ((fseek(za->zp, (off_t)offset, SEEK_SET) < 0)) { _zip_error_set(&za->error, ZIP_ER_SEEK, errno); error = 1; break; @@ -326,8 +326,8 @@ de->uncomp_size = st.size; if ((st.valid & ZIP_STAT_COMP_SIZE) == 0) { - if ((((de->comp_method == ZIP_CM_DEFLATE || ZIP_CM_IS_DEFAULT(de->comp_method)) && st.size > MAX_DEFLATE_SIZE_32) - || de->comp_method != ZIP_CM_STORE && de->comp_method != ZIP_CM_DEFLATE && !ZIP_CM_IS_DEFAULT(de->comp_method))) + if (( ((de->comp_method == ZIP_CM_DEFLATE || ZIP_CM_IS_DEFAULT(de->comp_method)) && st.size > MAX_DEFLATE_SIZE_32) + || (de->comp_method != ZIP_CM_STORE && de->comp_method != ZIP_CM_DEFLATE && !ZIP_CM_IS_DEFAULT(de->comp_method)))) flags |= ZIP_FL_FORCE_ZIP64; } else @@ -423,7 +423,7 @@ de->comp_method = st.comp_method; de->crc = st.crc; de->uncomp_size = st.size; - de->comp_size = offend - offdata; + de->comp_size = (zip_uint64_t)(offend - offdata); if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0)) _zip_dirent_torrent_normalize(de);
diff --git a/lib/zip_file_get_offset.c b/lib/zip_file_get_offset.c index f2742ec..0bd1b10 100644 --- a/lib/zip_file_get_offset.c +++ b/lib/zip_file_get_offset.c
@@ -68,5 +68,10 @@ if ((size=_zip_dirent_size(za->zp, ZIP_EF_LOCAL, error)) < 0) return 0; + if (offset+(zip_uint32_t)size > ZIP_OFF_MAX) { + _zip_error_set(error, ZIP_ER_SEEK, EFBIG); + return 0; + } + return offset + (zip_uint32_t)size; }
diff --git a/lib/zip_open.c b/lib/zip_open.c index 9e4b36f..8904e2a 100644 --- a/lib/zip_open.c +++ b/lib/zip_open.c
@@ -518,7 +518,7 @@ match = buf+ (buflen < CDBUFSIZE ? 0 : EOCD64LOCLEN); _zip_error_set(&zerr, ZIP_ER_NOZIP, 0); - while ((match=_zip_memmem(match, buflen-(match-buf)-(EOCDLEN-4), + while ((match=_zip_memmem(match, buflen-(size_t)(match-buf)-(EOCDLEN-4), (const unsigned char *)EOCD_MAGIC, 4))!=NULL) { /* found match -- check, if good */ /* to avoid finding the same match all over again */ @@ -571,8 +571,7 @@ return NULL; p = big-1; while ((p=(const unsigned char *) - memchr(p+1, little[0], (size_t)(big-(p+1)+biglen-littlelen+1))) - != NULL) { + memchr(p+1, little[0], (size_t)(big-(p+1))+(size_t)(biglen-littlelen)+1)) != NULL) { if (memcmp(p+1, little+1, littlelen-1)==0) return (unsigned char *)p; } @@ -631,24 +630,28 @@ zip_uint64_t offset; const zip_uint8_t *cdp; zip_uint8_t eocd[EOCD64LEN]; - off_t eocd_offset; - zip_uint64_t read_offset; + zip_uint64_t eocd_offset; zip_uint64_t size, nentry, i; cdp = eocd64loc+8; - read_offset = _zip_read8(&cdp); - /* XXX: check for off_t overflow */ - eocd_offset = (off_t)read_offset; + eocd_offset = _zip_read8(&cdp); + + if (eocd64loc < buf) + + if (eocd_offset > ZIP_OFF_MAX || eocd_offset + EOCD64LEN > ZIP_OFF_MAX) { + _zip_error_set(error, ZIP_ER_SEEK, EFBIG); + return NULL; + } - if (eocd_offset+EOCD64LEN > buf_offset+(eocd64loc-buf)) { + if (eocd64loc < buf || (off_t)eocd_offset+EOCD64LEN > (buf_offset+(eocd64loc-buf))) { _zip_error_set(error, ZIP_ER_INCONS, 0); return NULL; } - if (eocd_offset >= buf_offset && eocd_offset+EOCD64LEN <= buf_offset+(ssize_t)buflen) - cdp = buf+(eocd_offset-buf_offset); + if ((off_t)eocd_offset >= buf_offset && (off_t)eocd_offset+EOCD64LEN <= buf_offset+(ssize_t)buflen) + cdp = buf+((off_t)eocd_offset-buf_offset); else { - if (fseeko(f, eocd_offset, SEEK_SET) != 0) { + if (fseeko(f, (off_t)eocd_offset, SEEK_SET) != 0) { _zip_error_set(error, ZIP_ER_SEEK, errno); return NULL; } @@ -675,7 +678,7 @@ size = _zip_read8(&cdp); - if ((flags & ZIP_CHECKCONS) && size+eocd_offset+12 != buf_offset+(eocd64loc-buf)) { + if ((flags & ZIP_CHECKCONS) && size+eocd_offset+12 != (zip_uint64_t)(buf_offset+(eocd64loc-buf))) { _zip_error_set(error, ZIP_ER_INCONS, 0); return NULL; } @@ -694,6 +697,10 @@ size = _zip_read8(&cdp); offset = _zip_read8(&cdp); + if (size > ZIP_OFF_MAX || offset > ZIP_OFF_MAX) { + _zip_error_set(error, ZIP_ER_SEEK, EFBIG); + return NULL; + } if ((flags & ZIP_CHECKCONS) && offset+size != eocd_offset) { _zip_error_set(error, ZIP_ER_INCONS, 0); return NULL; @@ -702,8 +709,9 @@ if ((cd=_zip_cdir_new(nentry, error)) == NULL) return NULL; + cd->size = size; - cd->offset = offset; + cd->offset = (off_t)offset; return cd; }
diff --git a/lib/zipint.h b/lib/zipint.h index 84d377e..fae8177 100644 --- a/lib/zipint.h +++ b/lib/zipint.h
@@ -98,7 +98,15 @@ #endif #endif - +#if SIZEOF_OFF_T == 8 +#define ZIP_OFF_MAX ZIP_INT64_MAX +#elif SIZEOF_OFF_T == 4 +#define ZIP_OFF_MAX ZIP_INT32_MAX +#elif SIZEOF_OFF_T == 2 +#define ZIP_OFF_MAX ZIP_INT16_MAX +#else +#error unsupported size of off_t +#endif #define CENTRAL_MAGIC "PK\1\2" #define LOCAL_MAGIC "PK\3\4"