Я заметил, что некоторые из моих кодов декодирования gzip, похоже, не могли обнаружить поврежденные данные. Я думаю, что я проследил проблему до класса Java GZipInputStream. В частности, кажется, что когда вы читаете весь поток с помощью одного вызова read, поврежденные данные не вызывают IOException. Если вы читаете поток в двух или более вызовах с одними и теми же поврежденными данными, это вызывает исключение.
Я хотел узнать, что думает здесь сообщество, прежде чем я подумаю о подаче отчета об ошибке.
EDIT: У меня есть изменил мой пример, потому что последний не так ясно проиллюстрировал то, что я считаю проблемой. В этом новом примере 10-байтовый буфер сжат с помощью gzip, один байт буфера с gzip-сжатием модифицируется, а затем разархивируется. Вызов GZipInputStream.read возвращает 10 как количество прочитанных байтов, чего и следовало ожидать от 10-байтового буфера. Тем не менее, разархивированный буфер отличается от оригинала (из-за повреждения). Никаких исключений не создается. Я заметил, что вызов «доступно» после чтения возвращает «1» вместо «0», что было бы, если бы был достигнут EOF.
Вот источник:
@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();
}
}