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