diff -rup a/crypt.c b/crypt.c --- a/crypt.c 2007-01-05 07:47:36.000000000 -0800 +++ b/crypt.c 2016-11-30 13:13:47.569570000 -0800 @@ -465,7 +465,17 @@ int decrypt(__G__ passwrd) GLOBAL(pInfo->encrypted) = FALSE; defer_leftover_input(__G); for (n = 0; n < RAND_HEAD_LEN; n++) { - b = NEXTBYTE; + /* 2012-11-23 SMS. (OUSPG report.) + * Quit early if compressed size < HEAD_LEN. The resulting + * error message ("unable to get password") could be improved, + * but it's better than trying to read nonexistent data, and + * then continuing with a negative G.csize. (See + * fileio.c:readbyte()). + */ + if ((b = NEXTBYTE) == (ush)EOF) + { + return PK_ERR; + } h[n] = (uch)b; Trace((stdout, " (%02x)", h[n])); } diff -rup a/extract.c b/extract.c --- a/extract.c 2009-03-13 18:32:52.000000000 -0700 +++ b/extract.c 2016-11-30 13:23:26.163704000 -0800 @@ -1255,8 +1255,17 @@ static int extract_or_test_entrylist(__G if (G.lrec.compression_method == STORED) { zusz_t csiz_decrypted = G.lrec.csize; - if (G.pInfo->encrypted) + if (G.pInfo->encrypted) { + if (csiz_decrypted <= 12) { + /* handle the error now to prevent unsigned overflow */ + Info(slide, 0x401, ((char *)slide, + LoadFarStringSmall(ErrUnzipNoFile), + LoadFarString(InvalidComprData), + LoadFarStringSmall2(Inflate))); + return PK_ERR; + } csiz_decrypted -= 12; + } if (G.lrec.ucsize != csiz_decrypted) { Info(slide, 0x401, ((char *)slide, LoadFarStringSmall2(WrnStorUCSizCSizDiff), @@ -2701,6 +2710,12 @@ __GDEF int repeated_buf_err; bz_stream bstrm; + if (G.incnt <= 0 && G.csize <= 0L) { + /* avoid an infinite loop */ + Trace((stderr, "UZbunzip2() got empty input\n")); + return 2; + } + #if (defined(DLL) && !defined(NO_SLIDE_REDIR)) if (G.redirect_slide) wsize = G.redirect_size, redirSlide = G.redirect_buffer;