내 gzip 디코딩 코드 중 일부가 손상된 데이터를 감지하지 못하는 것으로 나타났습니다. Java GZipInputStream 클래스에서이 문제를 추적했다고 생각합니다. 특히, 단일 '읽기'호출로 전체 스트림을 읽을 때 손상된 데이터가 IOException을 유발하지 않는 것으로 보입니다. 동일한 손상된 데이터에서 둘 이상의 호출로 스트림을 읽으면 예외가 트리거됩니다.Java GZipInputStream 클래스의 버그입니까?
버그 보고서를 제출하기 전에 커뮤니티가 생각한 것을보고 싶었습니다.
편집 : 마지막 예제는 내가 문제로 인식하는 것을 분명하게 보여주지 않았기 때문에 예제를 수정했습니다. 이 새로운 예제에서는 10 바이트 버퍼가 gzip되고, gzipped 버퍼의 1 바이트가 수정 된 다음 ungzipped입니다. 'GZipInputStream.read'에 대한 호출은 읽은 바이트의 수를 10으로 반환합니다. 이는 10 바이트 버퍼에 대해 예상 한 것입니다. 그럼에도 압축 해제 된 버퍼는 원본과 다릅니다 (손상으로 인해). 예외는 발생하지 않습니다. 나는 EOF에 도달했을 때 '0'대신 '1'을 반환 한 후 'available'을 호출하는 것을 주목했습니다.
당신이 놓친 것 :
@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 좋은 질문; 자급 자족, 간결한, 실행 가능한 예제로 잘 작성되었습니다. 이것이 바로 당신이 그런 빠른 대답을 얻은 이유입니다 :-) –