GoogleContainerTools / GoogleContainerTools/jib

jib-core: ReproducibleLayerBuilder blob improperly closes the output stream

Open
#4,505 2 comments 0 reactions 0 assignees View on GitHub
priority: p3 type:bug
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.