Is this a bug in the Java GZipInputStream class?

a 夏天 提交于 2019-12-08 16:51:26

问题


I noticed that some of my gzip decoding code seemed to be failing to detect corrupted data. I think that I have traced the problem to the Java GZipInputStream class. In particular, it seems that when you read the entire stream with a single 'read' call, corrupted data doesn't trigger an IOException. If you read the stream in 2 or more calls on the same corrupted data, then it does trigger an exception.

I wanted to see what the community here thought before I consider filing a bug report.

EDIT: I have modified my example because the last one did not as clearly illustrate what I perceive to be the issue. In this new example, a 10 byte buffer is gzipped, one byte of the gzipped buffer is modified, then it is ungzipped. The call to 'GZipInputStream.read' returns 10 as the number of bytes read, which is what you would expect for a 10 byte buffer. Nevertheless, the unzipped buffer is different than the original (due to the corruption). No exception is thrown. I did note that calling 'available' after the read returns '1' instead of '0' which it would if the EOF had been reached.

Here is the source:

  @Test public void gzip() {
    try {
      int length = 10;
      byte[] bytes = new byte[]{12, 19, 111, 14, -76, 34, 60, -43, -91, 101};
      System.out.println(Arrays.toString(bytes));

      //Gzip the byte array
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      GZIPOutputStream gos = new GZIPOutputStream(baos);
      gos.write(bytes);
      gos.finish();
      byte[] zipped = baos.toByteArray();

      //Alter one byte of the gzipped array.  
      //This should be detected by gzip crc-32 checksum
      zipped[15] = (byte)(0);

      //Unzip the modified array
      ByteArrayInputStream bais = new ByteArrayInputStream(zipped);
      GZIPInputStream gis = new GZIPInputStream(bais);
      byte[] unzipped = new byte[length];
      int numRead = gis.read(unzipped);
      System.out.println("NumRead: " + numRead);
      System.out.println("Available: " + gis.available());

      //The unzipped array is now [12, 19, 111, 14, -80, 0, 0, 0, 10, -118].
      //No IOException was thrown.
      System.out.println(Arrays.toString(unzipped));

      //Assert that the input and unzipped arrays are equal (they aren't)
      org.junit.Assert.assertArrayEquals(unzipped, bytes);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

回答1:


Decided to run the test:

What you have missed. gis.read(unzipped) returns 1, so it has read only a single byte. You can't complain, it's not the end of the stream.

The next read() throws "Corrupt GZIP trailer".

So it's all good! (and there are no bugs, at least in GZIPInputStream)



来源:https://stackoverflow.com/questions/5276626/is-this-a-bug-in-the-java-gzipinputstream-class

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!