这是Java GZipInputStream类中的错误吗? [英] Is this a bug in the Java GZipInputStream class?

查看:143
本文介绍了这是Java GZipInputStream类中的错误吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我注意到我的某些gzip解码代码似乎无法检测到损坏的数据.我认为我已将问题追溯到Java GZipInputStream类.特别是,当您通过单个读取"调用读取整个流时,损坏的数据不会触发IOException.如果您在2次或更多次调用中读取了相同的损坏数据流,那么它将触发异常.

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.

我修改了我的示例,因为最后一个示例没有清楚地说明我认为的问题.在这个新示例中,将10字节的缓冲区压缩,然后将已压缩的缓冲区的一个字节修改,然后将其取消压缩.调用"GZipInputStream.read"将返回10作为读取的字节数,这是您期望的10字节缓冲区.但是,解压缩后的缓冲区与原始缓冲区不同(由于损坏).没有异常被抛出.我确实注意到,读取后调用"available"将返回"1"而不是"0"(如果已达到EOF则将返回).

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.

以下是来源:

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

推荐答案

决定运行测试:

您错过了什么. gis.read(unzipped)返回1,因此它仅读取一个字节.您不能抱怨,这不是流的尽头.

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.

下一个read()抛出腐败的GZIP预告片" .

一切都很好! (,至少在GZIPInputStream 中没有错误)

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

这篇关于这是Java GZipInputStream类中的错误吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆