Skip to content

Commit

Permalink
Determine Zip64 status entry-by-entry instead of for entire file.
Browse files Browse the repository at this point in the history
Fixes a bug for zip files with mixed Zip64 and not Zip64 entries,
which resulted in an incorrect data descriptor length. The bug is
seen when a Zip64 entry precedes a non-Zip64 entry, in which case
the data descriptor would have been assumed to be larger than it
is, resulting in an incorrect bomb warning due to a perceived
overlap with the next entry. This commit determines and saves the
Zip64 status for each entry based on the central directory, and
then computes the length of each data descriptor accordingly.
  • Loading branch information
madler committed Jan 2, 2021
1 parent b0993a3 commit 122050b
Show file tree
Hide file tree
Showing 4 changed files with 5 additions and 7 deletions.
5 changes: 3 additions & 2 deletions extract.c
Original file line number Diff line number Diff line change
Expand Up @@ -658,6 +658,7 @@ int extract_or_test_files(__G) /* return PK-type error code */
break;
}
}
G.pInfo->zip64 = FALSE;
if ((error = do_string(__G__ G.crec.extra_field_length,
EXTRA_FIELD)) != 0)
{
Expand Down Expand Up @@ -2187,12 +2188,12 @@ static int extract_or_test_member(__G) /* return PK-type error code */
(clen == SIG && /* if not SIG, no signature */
((G.lrec.csize & LOW) != SIG || /* if not SIG, have signature */
(ulen == SIG && /* if not SIG, no signature */
(G.zip64 ? G.lrec.csize >> 32 : G.lrec.ucsize) != SIG
(G.pInfo->zip64 ? G.lrec.csize >> 32 : G.lrec.ucsize) != SIG
/* if not SIG, have signature */
)))))
/* skip four more bytes to account for signature */
shy += 4 - readbuf((char *)buf, 4);
if (G.zip64)
if (G.pInfo->zip64)
shy += 8 - readbuf((char *)buf, 8); /* skip eight more for ZIP64 */
if (shy)
error = PK_ERR;
Expand Down
2 changes: 0 additions & 2 deletions globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -261,8 +261,6 @@ typedef struct Globals {
ecdir_rec ecrec; /* used in unzip.c, extract.c */
z_stat statbuf; /* used by main, mapname, check_for_newer */

int zip64; /* true if Zip64 info in extra field */

int mem_mode;
uch *outbufptr; /* extract.c static */
ulg outsize; /* extract.c static */
Expand Down
4 changes: 1 addition & 3 deletions process.c
Original file line number Diff line number Diff line change
Expand Up @@ -1903,8 +1903,6 @@ int getZip64Data(__G__ ef_buf, ef_len)
but it means that this procedure is only called in one place.
---------------------------------------------------------------------------*/

G.zip64 = FALSE;

if (ef_len == 0 || ef_buf == NULL)
return PK_COOL;

Expand Down Expand Up @@ -1943,7 +1941,7 @@ int getZip64Data(__G__ ef_buf, ef_len)
offset += sizeof(G.crec.disk_number_start);
}

G.zip64 = TRUE;
G.pInfo->zip64 = TRUE;
}

/* Skip this extra field block */
Expand Down
1 change: 1 addition & 0 deletions unzpriv.h
Original file line number Diff line number Diff line change
Expand Up @@ -2034,6 +2034,7 @@ typedef struct min_info {
#ifdef UNICODE_SUPPORT
unsigned GPFIsUTF8: 1; /* crec gen_purpose_flag UTF-8 bit 11 is set */
#endif
unsigned zip64: 1; /* true if entry has Zip64 extra block */
#ifndef SFX
char Far *cfilname; /* central header version of filename */
#endif
Expand Down

0 comments on commit 122050b

Please sign in to comment.