-
Bug
-
Resolution: Fixed
-
P4
-
8
-
generic
-
generic
FULL PRODUCT VERSION :
java version "1.8.0_102"
Java(TM) SE Runtime Environment (build 1.8.0_102-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.102-b14, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Linux rrosenbl-ld1 2.6.32-504.el6.x86_64 #1 SMP Tue Sep 16 01:56:35 EDT 2014 x86_64 x86_64 x86_64 GNU/Linux
A DESCRIPTION OF THE PROBLEM :
the implementation of InflaterInputStream.available():
public int available() throws IOException {
ensureOpen();
if (reachEOF) {
return 0;
} else {
return 1;
}
}
will return 1 in situations where the underlying inflater is actually finished, but has not been read() from (so no -1 seen). it seems that the condition in the method can be updated to :
public int available() throws IOException {
ensureOpen();
if (reachEOF || inf.finished()) {
return 0;
} else {
return 1;
}
}
such that available() will return 0 correctly (instead of returning available = 1 and the subsequent read() returning -1).
the impact of this is that if such an inflater stream is wrapped in a DataInputStream, the following code cannot work:
InflaterStream underlying = ...;
DataInsputStream decorator = ... //wrap underlying
while (underlying.available() > 0) {
//read something via decorator
}
with the current code the only option is to catch an EOF (thrown by DataInputStream in response to reading -1 as part of readFully())
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
the following code will reproduce the issue:
public static void main(String[] args) throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
GZIPOutputStream zos = new GZIPOutputStream(baos);
zos.write("some content".getBytes(Charset.forName("UTF-8")));
zos.close();
byte[] zippedBlob = baos.toByteArray();
GZIPInputStream zis = new GZIPInputStream(new ByteArrayInputStream(zippedBlob));
while (zis.available() > 0) {
int read = zis.read();
if (read == -1) {
System.err.println("you lied to me");
}
}
}
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
code should run with nothing printed to system.err
ACTUAL -
message printed to System.err indicating available() returned a positive value yet the subsequent read() returned -1
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
public static void main(String[] args) throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
GZIPOutputStream zos = new GZIPOutputStream(baos);
zos.write("some content".getBytes(Charset.forName("UTF-8")));
zos.close();
byte[] zippedBlob = baos.toByteArray();
GZIPInputStream zis = new GZIPInputStream(new ByteArrayInputStream(zippedBlob));
while (zis.available() > 0) {
int read = zis.read();
if (read == -1) {
System.err.println("you lied to me");
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
forced to catch the EOFException throws by DataInputStream in response to -1. this has a performance impact on my code.
java version "1.8.0_102"
Java(TM) SE Runtime Environment (build 1.8.0_102-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.102-b14, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Linux rrosenbl-ld1 2.6.32-504.el6.x86_64 #1 SMP Tue Sep 16 01:56:35 EDT 2014 x86_64 x86_64 x86_64 GNU/Linux
A DESCRIPTION OF THE PROBLEM :
the implementation of InflaterInputStream.available():
public int available() throws IOException {
ensureOpen();
if (reachEOF) {
return 0;
} else {
return 1;
}
}
will return 1 in situations where the underlying inflater is actually finished, but has not been read() from (so no -1 seen). it seems that the condition in the method can be updated to :
public int available() throws IOException {
ensureOpen();
if (reachEOF || inf.finished()) {
return 0;
} else {
return 1;
}
}
such that available() will return 0 correctly (instead of returning available = 1 and the subsequent read() returning -1).
the impact of this is that if such an inflater stream is wrapped in a DataInputStream, the following code cannot work:
InflaterStream underlying = ...;
DataInsputStream decorator = ... //wrap underlying
while (underlying.available() > 0) {
//read something via decorator
}
with the current code the only option is to catch an EOF (thrown by DataInputStream in response to reading -1 as part of readFully())
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
the following code will reproduce the issue:
public static void main(String[] args) throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
GZIPOutputStream zos = new GZIPOutputStream(baos);
zos.write("some content".getBytes(Charset.forName("UTF-8")));
zos.close();
byte[] zippedBlob = baos.toByteArray();
GZIPInputStream zis = new GZIPInputStream(new ByteArrayInputStream(zippedBlob));
while (zis.available() > 0) {
int read = zis.read();
if (read == -1) {
System.err.println("you lied to me");
}
}
}
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
code should run with nothing printed to system.err
ACTUAL -
message printed to System.err indicating available() returned a positive value yet the subsequent read() returned -1
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
public static void main(String[] args) throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
GZIPOutputStream zos = new GZIPOutputStream(baos);
zos.write("some content".getBytes(Charset.forName("UTF-8")));
zos.close();
byte[] zippedBlob = baos.toByteArray();
GZIPInputStream zis = new GZIPInputStream(new ByteArrayInputStream(zippedBlob));
while (zis.available() > 0) {
int read = zis.read();
if (read == -1) {
System.err.println("you lied to me");
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
forced to catch the EOFException throws by DataInputStream in response to -1. this has a performance impact on my code.
- duplicates
-
JDK-7031075 GZIPInputStream's available() reports 1, but read() gives -1.
-
- Resolved
-
-
JDK-7031075 GZIPInputStream's available() reports 1, but read() gives -1.
-
- Resolved
-