Это ошибка в классе Java GZipInputStream? - PullRequest
10 голосов
/ 11 марта 2011

Я заметил, что некоторые из моих кодов декодирования 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();
    }
  }

1 Ответ

9 голосов
/ 11 марта 2011

Решили запустить тест:

Что вы пропустили.gis.read(unzipped) возвращает 1, поэтому он прочитал только один байт.Вы не можете жаловаться, это не конец потока.

Следующее read() бросает "Corrupt GZIP Trailer" .

Так что все хорошо!( и ошибок нет, по крайней мере, в GZIPInputStream )

...