8074579: Use more efficient and readable way of checking PKZIP signatures

Reviewed-by: sherman
This commit is contained in:
Martin Buchholz 2015-03-10 14:23:03 -07:00
parent f825d1ff35
commit 0d022c42c9
5 changed files with 30 additions and 32 deletions

View File

@ -32,13 +32,16 @@
* Zip file header signatures
*/
#define SIGSIZ 4 /* size of all header signatures */
#define LOCSIG 0x04034b50L /* "PK\003\004" */
#define EXTSIG 0x08074b50L /* "PK\007\008" */
#define CENSIG 0x02014b50L /* "PK\001\002" */
#define ENDSIG 0x06054b50L /* "PK\005\006" */
#define ZIP64_ENDSIG 0x06064b50L /* "PK\006\006" */
#define ZIP64_LOCSIG 0x07064b50L /* "PK\006\007" */
#define PKZIP_SIGNATURE_AT(p, b2, b3) \
(((p)[0] == 'P') & ((p)[1] == 'K') & ((p)[2] == b2) & ((p)[3] == b3))
#define CENSIG_AT(p) PKZIP_SIGNATURE_AT(p, 1, 2)
#define LOCSIG_AT(p) PKZIP_SIGNATURE_AT(p, 3, 4)
#define ENDSIG_AT(p) PKZIP_SIGNATURE_AT(p, 5, 6)
#define EXTSIG_AT(p) PKZIP_SIGNATURE_AT(p, 7, 8)
#define ZIP64_ENDSIG_AT(p) PKZIP_SIGNATURE_AT(p, 6, 6)
#define ZIP64_LOCSIG_AT(p) PKZIP_SIGNATURE_AT(p, 6, 7)
/*
* Header sizes including signatures
*/

View File

@ -138,7 +138,7 @@ find_end64(int fd, Byte *ep, jlong pos)
return -1;
if ((bytes = read(fd, ep, ZIP64_LOCHDR)) < 0)
return -1;
if (GETSIG(ep) == ZIP64_LOCSIG)
if (ZIP64_LOCSIG_AT(ep))
return end64pos;
return -1;
}
@ -176,7 +176,7 @@ find_end(int fd, Byte *eb)
return (-1);
if ((bytes = read(fd, eb, ENDHDR)) < 0)
return (-1);
if (GETSIG(eb) == ENDSIG) {
if (ENDSIG_AT(eb)) {
return haveZIP64(eb) ? find_end64(fd, eb, pos) : pos;
}
@ -200,14 +200,11 @@ find_end(int fd, Byte *eb)
/*
* Search backwards from the end of file stopping when the END header
* signature is found. (The first condition of the "if" is just a
* fast fail, because the GETSIG macro isn't always cheap. The
* final condition protects against false positives.)
* signature is found.
*/
endpos = &buffer[bytes];
for (cp = &buffer[bytes - ENDHDR]; cp >= &buffer[0]; cp--)
if ((*cp == (ENDSIG & 0xFF)) && (GETSIG(cp) == ENDSIG) &&
(cp + ENDHDR + ENDCOM(cp) == endpos)) {
if (ENDSIG_AT(cp) && (cp + ENDHDR + ENDCOM(cp) == endpos)) {
(void) memcpy(eb, cp, ENDHDR);
free(buffer);
pos = flen - (endpos - cp);
@ -267,7 +264,7 @@ compute_cen(int fd, Byte *bp)
if ((bytes = read(fd, buffer, MINREAD)) < 0) {
return (-1);
}
if (GETSIG(buffer) != ZIP64_ENDSIG) {
if (!ZIP64_ENDSIG_AT(buffer)) {
return -1;
}
if ((offset = ZIP64_ENDOFF(buffer)) < (jlong)0) {
@ -356,7 +353,7 @@ find_file(int fd, zentry *entry, const char *file_name)
* Loop through the Central Directory Headers. Note that a valid zip/jar
* must have an ENDHDR (with ENDSIG) after the Central Directory.
*/
while (GETSIG(p) == CENSIG) {
while (CENSIG_AT(p)) {
/*
* If a complete header isn't in the buffer, shift the contents
@ -403,7 +400,7 @@ find_file(int fd, zentry *entry, const char *file_name)
free(buffer);
return (-1);
}
if (GETSIG(locbuf) != LOCSIG) {
if (!LOCSIG_AT(locbuf)) {
free(buffer);
return (-1);
}

View File

@ -281,9 +281,9 @@ static jboolean verifyEND(jzfile *zip, jlong endpos, char *endbuf) {
return (cenpos >= 0 &&
locpos >= 0 &&
readFullyAt(zip->zfd, buf, sizeof(buf), cenpos) != -1 &&
GETSIG(buf) == CENSIG &&
CENSIG_AT(buf) &&
readFullyAt(zip->zfd, buf, sizeof(buf), locpos) != -1 &&
GETSIG(buf) == LOCSIG);
LOCSIG_AT(buf));
}
/*
@ -674,7 +674,7 @@ readCEN(jzfile *zip, jint knownTotal)
method = CENHOW(cp);
nlen = CENNAM(cp);
if (GETSIG(cp) != CENSIG)
if (!CENSIG_AT(cp))
ZIP_FORMAT_ERROR("invalid CEN header (bad signature)");
if (CENFLG(cp) & 1)
ZIP_FORMAT_ERROR("invalid CEN header (encrypted entry)");
@ -827,10 +827,7 @@ ZIP_Put_In_Cache0(const char *name, ZFILE zfd, char **pmsg, jlong lastModified,
// Assumption, zfd refers to start of file. Trivially, reuse errbuf.
if (readFully(zfd, errbuf, 4) != -1) { // errors will be handled later
if (GETSIG(errbuf) == LOCSIG)
zip->locsig = JNI_TRUE;
else
zip->locsig = JNI_FALSE;
zip->locsig = LOCSIG_AT(errbuf) ? JNI_TRUE : JNI_FALSE;
}
len = zip->len = IO_Lseek(zfd, 0, SEEK_END);
@ -1284,7 +1281,7 @@ ZIP_GetEntryDataOffset(jzfile *zip, jzentry *entry)
zip->msg = "error reading zip file";
return -1;
}
if (GETSIG(loc) != LOCSIG) {
if (!LOCSIG_AT(loc)) {
zip->msg = "invalid LOC header (bad signature)";
return -1;
}

View File

@ -33,13 +33,14 @@
/*
* Header signatures
*/
#define LOCSIG 0x04034b50L /* "PK\003\004" */
#define EXTSIG 0x08074b50L /* "PK\007\008" */
#define CENSIG 0x02014b50L /* "PK\001\002" */
#define ENDSIG 0x06054b50L /* "PK\005\006" */
#define ZIP64_ENDSIG 0x06064b50L /* "PK\006\006" */
#define ZIP64_LOCSIG 0x07064b50L /* "PK\006\007" */
#define PKZIP_SIGNATURE_AT(p, b2, b3) \
(((p)[0] == 'P') & ((p)[1] == 'K') & ((p)[2] == b2) & ((p)[3] == b3))
#define CENSIG_AT(p) PKZIP_SIGNATURE_AT(p, 1, 2)
#define LOCSIG_AT(p) PKZIP_SIGNATURE_AT(p, 3, 4)
#define ENDSIG_AT(p) PKZIP_SIGNATURE_AT(p, 5, 6)
#define EXTSIG_AT(p) PKZIP_SIGNATURE_AT(p, 7, 8)
#define ZIP64_ENDSIG_AT(p) PKZIP_SIGNATURE_AT(p, 6, 6)
#define ZIP64_LOCSIG_AT(p) PKZIP_SIGNATURE_AT(p, 6, 7)
/*
* Header sizes including signatures

View File

@ -323,7 +323,7 @@ const char * isJar(const char * path) {
result = BAD_MAGIC_MSG;
// be sure the file is at least a ZIP file
if (GETSIG(buf) == LOCSIG) {
if (LOCSIG_AT(buf)) {
off_t flen = LOCNAM(buf);
off_t xlen = LOCEXT(buf);