我注意到我的gzip解码代码似乎无法检测到损坏的数据。我认为我已经找到了问题所在,是由于Java GZipInputStream类。特别是,当你用一个单独的“read”调用读取整个流时,损坏的数据不会触发IOException。如果你在同一段损坏的数据上进行2次或更多次的读取,则会触发异常。
在考虑提交错误报告之前,我想知道这里的社区对此有何看法。
编辑:我修改了我的示例,因为上一个示例没有清楚地说明我认为的问题。在这个新的示例中,一个10字节的缓冲区被压缩,修改了一个字节的压缩缓冲区,然后被解压缩。调用“GZipInputStream.read”返回读取的字节数为10,这是一个10字节缓冲区的预期值。然而,未压缩的缓冲区与原始缓冲区不同(由于损坏)。没有抛出异常。我注意到,在读取后调用“available”返回“1”,而不是达到EOF时应该返回的“0”。
以下是源代码:
在考虑提交错误报告之前,我想知道这里的社区对此有何看法。
编辑:我修改了我的示例,因为上一个示例没有清楚地说明我认为的问题。在这个新的示例中,一个10字节的缓冲区被压缩,修改了一个字节的压缩缓冲区,然后被解压缩。调用“GZipInputStream.read”返回读取的字节数为10,这是一个10字节缓冲区的预期值。然而,未压缩的缓冲区与原始缓冲区不同(由于损坏)。没有抛出异常。我注意到,在读取后调用“available”返回“1”,而不是达到EOF时应该返回的“0”。
以下是源代码:
@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();
}
}