< prev index next >
src/jdk.pack200/share/native/common-unpack/zip.cpp
Print this page
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
@@ -339,10 +339,11 @@
// Open a Jar file and initialize.
void jar::openJarFile(const char* fname) {
if (!jarfp) {
PRINTCR((1, "jar::openJarFile: opening %s\n",fname));
+ jarname = fname;
jarfp = fopen(fname, "wb");
if (!jarfp) {
fprintf(u->errstrm, "Error: Could not open jar file: %s\n",fname);
exit(3); // Called only from the native standalone unpacker
}
@@ -549,11 +550,12 @@
if (error != Z_OK && error != Z_STREAM_END) {
u->abort("error inflating input");
break;
}
int nr = readlen - zs.avail_out;
- u->gzcrc = crc32(u->gzcrc, (const unsigned char *)bufptr, nr);
+ u->gzin->gzlen += nr;
+ u->gzin->gzcrc = crc32(u->gzin->gzcrc, (const unsigned char *)bufptr, nr);
numread += nr;
bufptr += nr;
assert(numread <= maxlen);
if (error == Z_STREAM_END) {
enum { TRAILER_LEN = 8 };
@@ -560,19 +562,48 @@
// skip 8-byte trailer
if (zs.avail_in >= TRAILER_LEN) {
zs.avail_in -= TRAILER_LEN;
} else {
// Bug: 5023768,we read past the TRAILER_LEN to see if there is
- // any extraneous data, as we don't support concatenated .gz
- // files just yet.
+ // any extraneous data, as we don't support concatenated .gz files.
int extra = (int) read_gzin_fn(u, inbuf, 1, inbuflen);
zs.avail_in += extra - TRAILER_LEN;
}
- // %%% should check final CRC and length here
// %%% should check for concatenated *.gz files here
if (zs.avail_in > 0)
u->abort("garbage after end of deflated input stream");
+
+ // at this point we know there are no trailing bytes,
+ // we are safe to get the crc and len.
+ if (u->gzin->gzcrc != 0) {
+ // Read the CRC information from the gzip container
+ fseek(u->infileptr, -TRAILER_LEN, SEEK_END);
+ uint filecrc;
+ uint filelen;
+ fread(&filecrc, sizeof(filecrc), 1, u->infileptr);
+ fread(&filelen, sizeof(filelen), 1, u->infileptr);
+ filecrc = SWAP_INT(filecrc);
+ filelen = SWAP_INT(filelen);
+ if (u->gzin->gzcrc != filecrc ||
+ // rfc1952; ISIZE is the input size modulo 2^32
+ u->gzin->gzlen != (filelen & 0xffffffff)) { // CRC error
+
+ PRINTCR((1, "crc: 0x%x 0x%x\n", u->gzin->gzcrc, filecrc));
+ PRINTCR((1, "len: 0x%x 0x%x\n", u->gzin->gzlen, filelen));
+
+ if (u->jarout != null) {
+ // save the file name first, if any
+ const char* outfile = u->jarout->jarname;
+ u->jarout->closeJarFile(false);
+ if (outfile != null) {
+ remove(outfile);
+ }
+ }
+ // Print out the error and exit with return code != 0
+ u->abort("CRC error, invalid compressed data.");
+ }
+ }
// pop this filter off:
u->gzin->free();
break;
}
}
@@ -588,11 +619,12 @@
assert(u->gzin == null); // once only, please
read_input_fn = (void*)u->read_input_fn;
zstream = NEW(z_stream, 1);
u->gzin = this;
u->read_input_fn = read_input_via_gzip;
- u->gzcrc = crc32(0, Z_NULL, 0);
+ u->gzin->gzcrc = crc32(0, Z_NULL, 0);
+ u->gzin->gzlen = 0;
}
void gunzip::start(int magic) {
assert((magic & GZIP_MAGIC_MASK) == GZIP_MAGIC);
int gz_flg = (magic & 0xFF); // keep "flg", discard other 3 bytes
< prev index next >