Я заметил, что некоторые из моих кодов декодирования gzip, похоже, не могут обнаружить поврежденные данные.Я думаю, что отследил проблему до класса Java GZipInputStream.В частности, кажется, что когда вы читаете весь поток одним вызовом read, поврежденные данные не вызывают IOException.Если вы читаете поток за 2 или более обращений к одним и тем же поврежденным данным, то это вызывает исключение.
Я хотел бы узнать, что думает сообщество, прежде чем я рассмотрю возможность отправки отчета об ошибке.
РЕДАКТИРОВАТЬ: я изменил свой пример, потому что последний не так ясно иллюстрировал то, что я считаю проблемой.В этом новом примере 10-байтовый буфер gzip-файл, один байт gzip-буфера модифицируется, затем он распаковывается.Вызов «GZipInputStream.read» возвращает 10 как число прочитанных байтов, что вы и ожидаете для 10-байтового буфера.Тем не менее, разархивированный буфер отличается от оригинала (из-за повреждения).Не исключение не выбрасывается.Я заметил, что вызов 'available' после чтения возвращает '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();
}
}