-
Type:
Bug
-
Resolution: Unresolved
-
Priority:
P5
-
Affects Version/s: 11, 25
-
Component/s: core-libs
-
generic
-
generic
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 ----------
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 ----------