gzip デコード コードの一部が、破損したデータの検出に失敗しているように見えることに気付きました。問題を Java GZipInputStream クラスまでたどったと思います。特に、単一の「読み取り」呼び出しでストリーム全体を読み取ると、破損したデータが IOException をトリガーしないようです。同じ破損データに対して 2 回以上の呼び出しでストリームを読み取ると、例外がトリガーされます。
バグ レポートの提出を検討する前に、ここのコミュニティがどう考えているかを知りたかったのです。
編集: 最後の例では、私が問題であると認識しているものを明確に示していなかったため、例を変更しました。この新しい例では、10 バイトのバッファーが gzip され、gzip されたバッファーの 1 バイトが変更されてから unzip されます。「GZipInputStream.read」を呼び出すと、読み取ったバイト数として 10 が返されます。これは、10 バイトのバッファーに期待される値です。それにもかかわらず、解凍されたバッファは元のものとは異なります (破損のため)。例外はスローされません。読み取り後に「available」を呼び出すと、EOF に達した場合の「0」ではなく「1」が返されることに注意してください。
ソースは次のとおりです。
@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();
}
}