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 ----