Является ли это ошибкой в ​​классе Java GZipInputStream?

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

Ответ 1

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

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

Следующий read() выдает "Коррумпированный трейлер GZIP".

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