InflaterInputStream and InflaterOutputStream behavioral inconsistency

XMLWordPrintable

      ADDITIONAL SYSTEM INFORMATION :
      openjdk 21.0.1 2023-10-17 LTS
      OpenJDK Runtime Environment Temurin-21.0.1+12 (build 21.0.1+12-LTS)
      OpenJDK 64-Bit Server VM Temurin-21.0.1+12 (build 21.0.1+12-LTS, mixed mode)

      A DESCRIPTION OF THE PROBLEM :
      I've noticed that InflaterInputStream and InflaterOutputStream handle corrupted DEFLATE data differently. When processing the same corrupted data (generated by Deflater.SYNC_FLUSH without finish()):

      - InflaterInputStream throws EOFException
      - InflaterOutputStream successfully decompresses the data

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Run the test case code

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Should both classes behave consistently? Should InflaterOutputStream also throw an exception when encountering corrupted/incomplete DEFLATE data, similar to InflaterInputStream?
      ACTUAL -
      InflaterOutputStream: Hello, World!
      java.io.EOFException: Unexpected end of ZLIB input stream
      at java.base/java.util.zip.InflaterInputStream.fill(InflaterInputStream.java:266)
      at java.base/java.util.zip.InflaterInputStream.read(InflaterInputStream.java:175)
      at java.base/java.io.InputStream.readNBytes(InputStream.java:412)
      at java.base/java.io.InputStream.readAllBytes(InputStream.java:349)
      at DiffInflaterStream.main(DiffInflaterStream.java:34)

      ---------- BEGIN SOURCE ----------
      import java.io.ByteArrayInputStream;
      import java.io.ByteArrayOutputStream;
      import java.io.IOException;
      import java.nio.charset.StandardCharsets;
      import java.util.zip.Deflater;
      import java.util.zip.InflaterInputStream;
      import java.util.zip.InflaterOutputStream;

      public class DiffInflaterStream {
          public static void main(String[] args) throws IOException {
              byte[] input = "Hello, World!".getBytes(StandardCharsets.UTF_8);
              Deflater def = new Deflater();
              def.setInput(input);
              //def.finish(); // <--- uncomment this line to fix the issue
              byte[] buffer = new byte[100];
              int compressedDataLength = def.deflate(buffer, 0, buffer.length, Deflater.SYNC_FLUSH); // <--- only occurs with Deflater.SYNC_FLUSH and without def.finish()
              byte[] compressedData = new byte[compressedDataLength];
              System.arraycopy(buffer, 0, compressedData, 0, compressedDataLength);
              def.end();

              // Decompress using InflaterOutputStream
              try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                   InflaterOutputStream inflaterOutputStream = new InflaterOutputStream(byteArrayOutputStream)) {
                  inflaterOutputStream.write(compressedData);
                  System.out.println("InflaterOutputStream: " + new String(byteArrayOutputStream.toByteArray(), StandardCharsets.UTF_8));
              } catch (Exception e) {
                  e.printStackTrace(System.out);
              }

              // Decompress using InflaterInputStream
              try (InflaterInputStream inflaterInputStream = new InflaterInputStream(new ByteArrayInputStream(compressedData))) {
                  System.out.println("InflaterInputStream: " + new String(inflaterInputStream.readAllBytes(), StandardCharsets.UTF_8));
              } catch (Exception e) {
                  e.printStackTrace(System.out);
              }

              // Why InflaterInputStream throws an exception and InflaterOutputStream doesn't?
          }
      }

      ---------- END SOURCE ----------

            Assignee:
            Lance Andersen
            Reporter:
            Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: