RFR: 8292327: java.io.EOFException in InflaterInputStream after JDK-8281962

Alan Bateman alanb at openjdk.org
Mon Aug 15 18:41:39 UTC 2022


On Mon, 15 Aug 2022 17:43:27 GMT, Volker Simonis <simonis at openjdk.org> wrote:

> The problem is that after [JDK-8281962](https://bugs.openjdk.org/browse/JDK-8292327) we call `fill()` unconditionally (and before calling `Inflater::inflate()`) in `InflaterInputStream::read()` if `Inflater::needsInput()` is true. This misses the case where the native inflater has consumed all its input (i.e. `Inflater::needsInput()` returns true) but hasn't managed to write all the inflated data into the output buffer (e.g. because it was to small). In rare cases, there might be now more input available (i.e. calling `InflaterInputStream::fill()` will throw an `EOFException`) but we still have to call `Inflater::inflate()` to consume the buffered output from the underlying native inflater until inflation stops. 
> 
> The documentation of the `inflate()` method in `zlib.h` mentions this explicitely:
> 
>> "If `inflate()` returns `Z_OK` and with zero `avail_out`, it must be called again after making room in the output buffer because there might be more output pending."

src/java.base/share/classes/java/util/zip/InflaterInputStream.java line 158:

> 156:                     return -1;
> 157:                 }
> 158:                 if (inf.needsInput() && !inf.hasPendingOutput()) {

I think the approach looks okay and avoids attempting to fill and the unspecified EOFException that it throws when the input is at EOF.

src/java.base/share/classes/java/util/zip/InflaterInputStream.java line 161:

> 159:                     // Even if needsInput() is true, the native inflater may have some
> 160:                     // buffered data which couldn't fit in to the output buffer during the
> 161:                     // last call to inflate. Consume that bffered data first before calling

bffered -> buffered

src/java.base/share/classes/java/util/zip/InflaterInputStream.java line 164:

> 162:                     // fill() to avoid an EOF error if no more input is available and the
> 163:                     // next call to inflate will finish the inflation.
> 164:                     fill();

We need to submit a bug against fill() too as it is not currently specified to throw when the input is at EOF.

test/jdk/java/util/zip/InflaterInputStream/EOF.java line 37:

> 35: import java.util.zip.InflaterInputStream;
> 36: 
> 37: public class EOF {

This is not a general purpose test for EOF so I think we'll need to find a better name.  BufferedBytesAtInputEOF might work.

Also the test doesn't check the output. We'll need to do that to make it a more complete test.

test/jdk/java/util/zip/InflaterInputStream/EOF.java line 61:

> 59:       n = is.read(buf, 0, 1); // Unexpected end of ZLIB input stream
> 60:     }
> 61:   }

Can you re-format this to use 4 space indent?

-------------

PR: https://git.openjdk.org/jdk/pull/9881


More information about the core-libs-dev mailing list