GoogleContainerTools / GoogleContainerTools/jib
jib-core: ReproducibleLayerBuilder blob improperly closes the output stream
- Dominant language
- Java
- Stars
- 14.5k
- Forks
- 1.5k
- PR merge metrics
- No merged PRs in 30d
Description
**Environment**:
- *Jib version:* jib-core: 0.28.1
- *Build tool:* gradle
- *OS:* Mac (irrelevant)
**Description of the issue**:
`ReproducibleLayerBuilder` builds a blob that first calls `close` on the underlying OutputStream (contrary to the javadoc), and then later calls `flush`, causing many OutputStream implementations to throw.
1) `ReproducibleLayerBuilder` uses `TarStreamBuilder` under the hood. It returns `Blobs.from(tarStreamBuilder::writeAsTarArchiveTo, false)`, which creates a `WriteableContentsBlob`.
2) `TarStreamBuilder.writeAsTarArchiveTo` uses try-with-resources, which closes the underlying OutputStream when finished.
3) `WriteableContentsBlob.writeTo` uses `Digests.computeDigest(writableContents, outputStream)`, which does this:
```java
CountingDigestOutputStream digestOutStream = new CountingDigestOutputStream(outStream);
contents.writeTo(digestOutStream);
digestOutStream.flush();
return digestOutStream.computeDigest();
```
Line 2 _closes_ the digestOutputStream (because of `writeAsTarArchiveTo`), so then line 3 flushes after close.
**Expected behavior**:
Blob.writeTo should never call close on the OutputStream. You should be able to use any OutputStream.
`TarStreamBuilder` should not close the output stream passed to it.
**Steps to reproduce**:
```java
ReproducibleLayerBuilder blob = new ReproducibleLayerBuilder(ImmutableList.of()).build();
// this causes ZstdOutputStream to throw IOException: StreamClosed
blob.writeTo(new ZstdOutputStream(new ByteArrayOutputStream()));
```
Contributor guide
Assessment
This issue has not been assessed yet.