Duplicate :
|
|
Relates :
|
|
Relates :
|
When inflating a file whose inflated size is 2GB or more, GZIPInputStream incorrectly throws IOException. The test program below compresses the specified number of double-words, then decompresses and verifies. Examples: $ java -server GzipTest file-64KB.gz 8192 File file-64KB.gz written. $ java -server GzipTest file-2GB.gz 268435456 File file-2GB.gz written. Exception in thread "main" java.lang.Error: Error reading at GzipTest.verify(GzipTest.java:82) at GzipTest.main(GzipTest.java:26) Caused by: java.io.IOException: Corrupt GZIP trailer at java.util.zip.GZIPInputStream.readTrailer(GZIPInputStream.java:174) at java.util.zip.GZIPInputStream.read(GZIPInputStream.java:89) at GzipTest.verify(GzipTest.java:67) ... 1 more $ cat GzipTest.java import java.io.*; import java.nio.ByteBuffer; import java.util.zip.*; public class GzipTest { private static final byte[] PI; static { ByteBuffer bb = ByteBuffer.allocate(8); bb.putDouble(Math.PI); PI = bb.array(); } private final File file; private final int count; public static void main(String[] args) { if (args.length != 2) { System.err.println("Usage: GzipTest <filename.gz> <count>"); System.exit(1); } File outputFile = new File(args[0]); GzipTest test = new GzipTest(outputFile, Integer.parseInt(args[1])); test.write(); System.out.println("File " + args[0] + " written."); if (test.verify()) { System.err.println("Verification FAILED!"); } } public GzipTest(File file, int count) { this.file = file; this.count = count; } /** Writes count copies of PI to a compressed file. */ public void write() { GZIPOutputStream gzipper; try { gzipper = new GZIPOutputStream(new FileOutputStream(file)); } catch (IOException error) { throw new IllegalArgumentException("Error opening " + file); } try { for (int i = 0; i < count; i++) { gzipper.write(PI, 0, 8); } gzipper.close(); } catch (IOException e) { throw new Error("Error writing", e); } } /** Returns true on error. */ public boolean verify() { GZIPInputStream gunzipper; try { gunzipper = new GZIPInputStream(new FileInputStream(file)); } catch (IOException error) { throw new IllegalArgumentException("Error opening " + file); } byte[] input = new byte[8]; try { for (int i = 0; true; i++) { int pos = 0; do { int read = gunzipper.read(input, pos, input.length - pos); if (read < 0) { gunzipper.close(); return i != count; } pos += read; } while (input.length - pos > 0); for (int j = 0; j < input.length; j++) { if (input[j] != PI[j]) { gunzipper.close(); return true; } } } } catch (IOException e) { throw new Error("Error reading", e); } } }
|