Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-5092263

GZIPInputStream spuriously reports "Corrupt GZIP trailer" for sizes > 2GB

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P3 P3
    • 6
    • 5.0, 6
    • core-libs
    • None
    • b31
    • x86, sparc
    • solaris_10, windows_xp

        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);
                }
            }
        }

              martin Martin Buchholz
              duke J. Duke
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

                Created:
                Updated:
                Resolved:
                Imported:
                Indexed: