Summary
-------
If the underlying `OutputStream` associated with `ZipOutputStream` or `GZIPOutputStream` throws an `IOException` while the zip stream is being closed, the associated compressor is left in an inconsistent state and may cause infinite looping.
Problem
-------
If a call to `GZIPOutputStream.close()`, `GZIPOutputStream.finish()` or `ZipOutputStream.closeEntry()` results in an `IOException`, an call to `GZIPOutputStream.write()` or `ZipOutputStream.write()` may result in an infinite loop.
Solution
--------
If an `IOException` is encountered while using the default JDK compressor in `GZIPOutputStream.finish()` or `ZipOutputStream.closeEntry()`, then close the compressor before propagating that Exception up the stack. `DeflaterOutputStream.close()` is hardened to ensure that the default JDK compressor is closed in case where `Throwable` is propagated up the stack. This will ensure that subsequent write operations using the same deflater will fail. An exception is made for the `ZipOutputStream.closeEntry()` call. For that method, IOExceptions of type `ZipException` will not cause the associated compressor to be closed.
Harden `DeflaterOutputStream.close()` to close out the associated default JDK compressor before propagating a `Throwable` (if any) up the stack
Harden `ZIPOutputStream.closeEntry()` to close out the associated default JDK compressor before propagating an `IOException`, not of type `ZipException`, (if any) up the stack
Harden `GZIPOutputStream.finish()` to close out the associated default JDK compressor before propagating an `IOException` (if any) up the stack
The behavioral change will be documented in a release note.
Specification
-------------
A future CSR may propose spec clarifications.