The fix is taken from http://www.info-zip.org/phpBB3/viewtopic.php?f=7&t=454
and should be available in next unzip release.
--- unzip60/extract.c Fri Feb 26 07:14:44 2016
+++ /home/vmarek/extract.c Mon Feb 22 08:32:56 2016
@@ -298,7 +298,7 @@
#ifndef SFX
static ZCONST char Far InconsistEFlength[] = "bad extra-field entry:\n \
EF block length (%u bytes) exceeds remaining EF data (%u bytes)\n";
- static ZCONST char Far TooSmallEFlength[] = "bad extra-field entry:\n \
+ static ZCONST char Far TooSmallEBlength[] = "bad extra-field entry:\n \
EF block length (%u bytes) invalid (< %d)\n";
static ZCONST char Far InvalidComprDataEAs[] =
" invalid compressed data for EAs\n";
@@ -2035,16 +2035,6 @@
ebLen, (ef_len - EB_HEADSIZE)));
return PK_ERR;
}
- else if (ebLen < EB_HEADSIZE)
- {
- /* Extra block length smaller than header length. */
- if (uO.qflag)
- Info(slide, 1, ((char *)slide, "%-22s ",
- FnFilter1(G.filename)));
- Info(slide, 1, ((char *)slide, LoadFarString(TooSmallEFlength),
- ebLen, EB_HEADSIZE));
- return PK_ERR;
- }
switch (ebID) {
case EF_OS2:
@@ -2171,11 +2161,19 @@
}
break;
case EF_PKVMS:
- if (makelong(ef+EB_HEADSIZE) !=
+ if (ebLen < 4)
+ {
+ Info(slide, 1,
+ ((char *)slide, LoadFarString(TooSmallEBlength),
+ ebLen, 4));
+ }
+ else if (makelong(ef+EB_HEADSIZE) !=
crc32(CRCVAL_INITIAL, ef+(EB_HEADSIZE+4),
(extent)(ebLen-4)))
+ {
Info(slide, 1, ((char *)slide,
LoadFarString(BadCRC_EAs)));
+ }
break;
case EF_PKW32:
case EF_PKUNIX:
@@ -2230,7 +2228,7 @@
ulg eb_ucsize;
uch *eb_ucptr;
int r;
- ush method;
+ ush eb_compr_method;
if (compr_offset < 4) /* field is not compressed: */
return PK_OK; /* do nothing and signal OK */
@@ -2247,11 +2245,14 @@
((eb_ucsize > 0L) && (eb_size <= (compr_offset + EB_CMPRHEADLEN))))
return IZ_EF_TRUNC; /* no/bad compressed data! */
- method = makeword(eb + (EB_HEADSIZE + compr_offset));
- if ((method == STORED) && (eb_size - compr_offset != eb_ucsize))
- return PK_ERR; /* compressed & uncompressed
- * should match in STORED
- * method */
+ /* 2015-02-10 Mancha(?), Michal Zalewski, Tomas Hoger, SMS.
+ * For STORE method, compressed and uncompressed sizes must agree.
+ */
+ eb_compr_method = makeword( eb + (EB_HEADSIZE + compr_offset));
+ if ((eb_compr_method == STORED) &&
+ (eb_size != compr_offset + EB_CMPRHEADLEN + eb_ucsize))
+ return PK_ERR;
if (
#ifdef INT_16BIT
@@ -2523,10 +2524,28 @@
__GDEF
slinkentry *slnk_entry;
{
+ int sts;
extent ucsize = slnk_entry->targetlen;
char *linkfname = slnk_entry->fname;
char *linktarget = (char *)malloc(ucsize+1);
+#ifdef VMS
+ static int vms_symlink_works = -1;
+
+ if (vms_symlink_works < 0)
+ {
+ /* Test symlink() with an invalid file name. If errno comes
+ * back ENOSYS ("Function not implemented"), then don't try to
+ * use it below on the symlink placeholder text files.
+ */
+ vms_symlink_works = symlink( "", "?");
+ if (errno == ENOSYS)
+ vms_symlink_works = 0;
+ else
+ vms_symlink_works = 1;
+ }
+#endif /* def VMS */
+
if (!linktarget) {
Info(slide, 0x201, ((char *)slide,
LoadFarString(SymLnkWarnNoMem), FnFilter1(linkfname)));
@@ -2554,11 +2573,29 @@
return;
}
fclose(G.outfile); /* close "data" file for good... */
+
+#ifdef VMS
+ if (vms_symlink_works == 0)
+ {
+ /* Should we be using some UnZip error message function instead
+ * of perror() (or equivalent) for these "symlink error"
+ * messages?
+ */
+ Info(slide, 0, ((char *)slide, LoadFarString(SymLnkFinish),
+ FnFilter1(linkfname), FnFilter2(linktarget)));
+
+ fprintf( stderr, "Symlink error: %s\n", strerror( ENOSYS));
+ free(linktarget);
+ return;
+ }
+#endif /* def VMS */
+
unlink(linkfname); /* ...and delete it */
- if (QCOND2)
+ sts = symlink(linktarget, linkfname); /* create the real link */
+ if (QCOND2 || (sts != 0))
Info(slide, 0, ((char *)slide, LoadFarString(SymLnkFinish),
FnFilter1(linkfname), FnFilter2(linktarget)));
- if (symlink(linktarget, linkfname)) /* create the real link */
+ if (sts != 0)
perror("symlink error");
free(linktarget);
#ifdef SET_SYMLINK_ATTRIBS
@@ -2652,7 +2689,7 @@
#endif /* ?HAVE_WORKING_ISPRINT */
} else {
#ifdef _MBCS
- unsigned i = CLEN(r);
+ extent i = CLEN(r);
if (se != NULL && (s > (space + (size-i-2)))) {
have_overflow = TRUE;
break;
@@ -2835,7 +2872,7 @@
#endif
G.inptr = (uch *)bstrm.next_in;
uzbunzip_cleanup_exit:
err = BZ2_bzDecompressEnd(&bstrm);