yegor256/rultor

`InputStream` from `Profile.assets()` is not closed in `PfShell.key()`

Open

#2,324 opened on May 11, 2026

View on GitHub
 (1 comment) (0 reactions) (0 assignees)Java (165 forks)github user discovery
bughelp wanted

Repository metrics

Stars
 (575 stars)
PR merge metrics
 (PR metrics pending)

Description

What happens

In src/main/java/com/rultor/agents/shells/PfShell.java, the key() method reads an SSH private key from a profile asset:

if (this.profile.assets().get(path) == null) {
    ...
}
return IOUtils.toString(
    this.profile.assets().get(path),
    StandardCharsets.UTF_8
);

Profile.assets() is declared (src/main/java/com/rultor/spi/Profile.java:65) as returning Map<String, InputStream> — the values are raw InputStream instances that the caller owns. Apache commons-io IOUtils.toString(InputStream, Charset) reads the stream to a string but does not close it.

The method therefore obtains an InputStream (at line 128 for the null check, and again at line 134 for the read) and discards both references without closing them. Depending on the Profile implementation, this may be a memory-backed stream (cheap leak) or a network/file-backed stream (real file-descriptor leak that accumulates across SSH key reads).

What should happen

Wrap both reads in try-with-resources, or obtain the stream once and reuse it:

try (InputStream stream = this.profile.assets().get(path)) {
    if (stream == null) {
        throw new IOException(...);
    }
    return IOUtils.toString(stream, StandardCharsets.UTF_8);
}

Result: the stream is deterministically closed, regardless of the underlying Profile implementation.

Contributor guide