src/share/classes/java/util/zip/GZIPInputStream.java
Print this page
*** 1,7 ****
/*
! * Copyright 1996-2006 Sun Microsystems, Inc. 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. Sun designates this
--- 1,7 ----
/*
! * Copyright 1996-2010 Sun Microsystems, Inc. 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. Sun designates this
*** 73,84 ****
* @exception IllegalArgumentException if size is <= 0
*/
public GZIPInputStream(InputStream in, int size) throws IOException {
super(in, new Inflater(true), size);
usesDefaultInflater = true;
! readHeader();
! crc.reset();
}
/**
* Creates a new input stream with a default buffer size.
* @param in the input stream
--- 73,83 ----
* @exception IllegalArgumentException if size is <= 0
*/
public GZIPInputStream(InputStream in, int size) throws IOException {
super(in, new Inflater(true), size);
usesDefaultInflater = true;
! readHeader(in);
}
/**
* Creates a new input stream with a default buffer size.
* @param in the input stream
*** 112,129 ****
public int read(byte[] buf, int off, int len) throws IOException {
ensureOpen();
if (eos) {
return -1;
}
! len = super.read(buf, off, len);
! if (len == -1) {
! readTrailer();
eos = true;
} else {
! crc.update(buf, off, len);
}
! return len;
}
/**
* Closes this input stream and releases any system resources associated
* with the stream.
--- 111,130 ----
public int read(byte[] buf, int off, int len) throws IOException {
ensureOpen();
if (eos) {
return -1;
}
! int n = super.read(buf, off, len);
! if (n == -1) {
! if (readTrailer())
eos = true;
+ else
+ return this.read(buf, off, len);
} else {
! crc.update(buf, off, n);
}
! return n;
}
/**
* Closes this input stream and releases any system resources associated
* with the stream.
*** 150,163 ****
private final static int FEXTRA = 4; // Extra field
private final static int FNAME = 8; // File name
private final static int FCOMMENT = 16; // File comment
/*
! * Reads GZIP member header.
*/
! private void readHeader() throws IOException {
! CheckedInputStream in = new CheckedInputStream(this.in, crc);
crc.reset();
// Check header magic
if (readUShort(in) != GZIP_MAGIC) {
throw new ZipException("Not in GZIP format");
}
--- 151,165 ----
private final static int FEXTRA = 4; // Extra field
private final static int FNAME = 8; // File name
private final static int FCOMMENT = 16; // File comment
/*
! * Reads GZIP member header and returns the total byte number
! * of this member header.
*/
! private int readHeader(InputStream this_in) throws IOException {
! CheckedInputStream in = new CheckedInputStream(this_in, crc);
crc.reset();
// Check header magic
if (readUShort(in) != GZIP_MAGIC) {
throw new ZipException("Not in GZIP format");
}
*** 167,201 ****
}
// Read flags
int flg = readUByte(in);
// Skip MTIME, XFL, and OS fields
skipBytes(in, 6);
// Skip optional extra field
if ((flg & FEXTRA) == FEXTRA) {
! skipBytes(in, readUShort(in));
}
// Skip optional file name
if ((flg & FNAME) == FNAME) {
! while (readUByte(in) != 0) ;
}
// Skip optional file comment
if ((flg & FCOMMENT) == FCOMMENT) {
! while (readUByte(in) != 0) ;
}
// Check optional header CRC
if ((flg & FHCRC) == FHCRC) {
int v = (int)crc.getValue() & 0xffff;
if (readUShort(in) != v) {
throw new ZipException("Corrupt GZIP header");
}
}
}
/*
! * Reads GZIP member trailer.
*/
! private void readTrailer() throws IOException {
InputStream in = this.in;
int n = inf.getRemaining();
if (n > 0) {
in = new SequenceInputStream(
new ByteArrayInputStream(buf, len - n, n), in);
--- 169,215 ----
}
// Read flags
int flg = readUByte(in);
// Skip MTIME, XFL, and OS fields
skipBytes(in, 6);
+ int n = 2 + 2 + 6;
// Skip optional extra field
if ((flg & FEXTRA) == FEXTRA) {
! int m = readUShort(in);
! skipBytes(in, m);
! n += m + 2;
}
// Skip optional file name
if ((flg & FNAME) == FNAME) {
! do {
! n++;
! } while (readUByte(in) != 0);
}
// Skip optional file comment
if ((flg & FCOMMENT) == FCOMMENT) {
! do {
! n++;
! } while (readUByte(in) != 0);
}
// Check optional header CRC
if ((flg & FHCRC) == FHCRC) {
int v = (int)crc.getValue() & 0xffff;
if (readUShort(in) != v) {
throw new ZipException("Corrupt GZIP header");
}
+ n += 2;
}
+ crc.reset();
+ return n;
}
/*
! * Reads GZIP member trailer and returns true if the eos
! * reached, false if there are more (concatenated gzip
! * data set)
*/
! private boolean readTrailer() throws IOException {
InputStream in = this.in;
int n = inf.getRemaining();
if (n > 0) {
in = new SequenceInputStream(
new ByteArrayInputStream(buf, len - n, n), in);
*** 203,213 ****
--- 217,245 ----
// Uses left-to-right evaluation order
if ((readUInt(in) != crc.getValue()) ||
// rfc1952; ISIZE is the input size modulo 2^32
(readUInt(in) != (inf.getBytesWritten() & 0xffffffffL)))
throw new ZipException("Corrupt GZIP trailer");
+
+ // If there are more bytes available in "in" or
+ // the leftover in the "inf" is > 26 bytes:
+ // this.trailer(8) + next.header.min(10) + next.trailer(8)
+ // try concatenated case
+ if (this.in.available() > 0 || n > 26) {
+ int m = 8; // this.trailer
+ try {
+ m += readHeader(in); // next.header
+ } catch (IOException ze) {
+ return true; // ignore any malformed, do nothing
}
+ inf.reset();
+ if (n > m)
+ inf.setInput(buf, len - n + m, n - m);
+ return false;
+ }
+ return true;
+ }
/*
* Reads unsigned integer in Intel byte order.
*/
private long readUInt(InputStream in) throws IOException {
*** 237,247 ****
+ ".read() returned value out of range -1..255: " + b);
}
return b;
}
-
private byte[] tmpbuf = new byte[128];
/*
* Skips bytes of input data blocking until all bytes are skipped.
* Does not assume that the input stream is capable of seeking.
--- 269,278 ----