guava icon indicating copy to clipboard operation
guava copied to clipboard

BaseEncoding.encodingStream().close() is non-idempotent

Open brettkail-wk opened this issue 4 years ago • 7 comments

Closeable.close says:

If the stream is already closed then invoking this method has no effect.

Code:

StringWriter w = new StringWriter();
OutputStream out = BaseEncoding.base64().encodingStream(w);
out.write(0);
out.close();
System.out.println(w);
out.close();
System.out.println(w);

Output:

AA==
AA==A===

brettkail-wk avatar Oct 16 '20 13:10 brettkail-wk

Thanks. For our reference, here is the implementation. The simplest thing is probably to mark all methods as synchronized and track isClosed in a boolean field. That may have some performance impact, but I'm not sure we can do better without giving up on thread-safety, which IO streams generally have (though I forget if it's actually guaranteed).

cpovirk avatar Oct 16 '20 13:10 cpovirk

It looks like the problem is just that close doesn't adjust bitBufferLength. I don't think thread-safety is required.

brettkail-wk avatar Oct 16 '20 14:10 brettkail-wk

Being idempotent is useful; it's very easy to double-close a stream due to ARM blocks and wrapping streams that close their underlying streams.

Synchronization is probably unnecessary. Java I/O streams are generally synchronized, but I've never seen anyone use multiple threads to concurrently read or write a shared stream.

swankjesse avatar Oct 16 '20 14:10 swankjesse

close doesn't adjust bitBufferLength @brettkail-wk I assumed you meant that it should go back to zero after closing, even if I'm not sure that it's descriptive of the stream's state.

Saucistophe avatar Oct 17 '20 23:10 Saucistophe

And while we're at it, @cpovirk, do you think it is possible to tag this repository with topic hacktoberfest? That would make this PR count towards my 4 PR goal - and my shirt! :shirt: :1234: Thanks :)

Saucistophe avatar Oct 19 '20 11:10 Saucistophe

@Saucistophe I have not analyzed the code. I just observed the condition for writing more bytes in close, and I noticed the similarity in structure to the write method, which does adjust bitBufferLength.

brettkail-wk avatar Oct 19 '20 14:10 brettkail-wk

I met the same issue, on guava 31.1-jre, is there any plan to have it fixed?

YuyuZha0 avatar Mar 13 '23 05:03 YuyuZha0