-
Notifications
You must be signed in to change notification settings - Fork 11.1k
Closed
Description
Using guava-23.0
(and earlier versions), com.google.common.io.MultiInputStream
produces a stack overflow when it is given sufficiently many empty ByteSource
instances.
Test cases that reproduce the behavior:
import java.io.InputStream;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import com.google.common.collect.Lists;
import com.google.common.io.ByteSource;
public class MultiInputStreamTest {
/** Adjust this according to the thread stack size. */
private static final int LARGE_ENOUGH_FOR_CURRENT_STACK_SIZE = 1000000;
private ByteSource concatenated;
public @Before void setup() throws Exception {
final List<ByteSource> emptySources = Lists.newArrayList();
for (int i = 0; i < LARGE_ENOUGH_FOR_CURRENT_STACK_SIZE; i++) {
emptySources.add(ByteSource.empty());
}
// produce a ConcatenatedByteSource which in turn produces
// a MultiInputStream
concatenated = ByteSource.concat(emptySources);
}
public @Test void stackOverflowErrorOnEmptySources1() throws Exception {
try (InputStream in = concatenated.openStream()) {
in.read();
}
}
public @Test void stackOverflowErrorOnEmptySources2() throws Exception {
try (InputStream in = concatenated.openStream()) {
in.read(new byte[1], 0, 1);
}
}
}
The condensed exception stack traces produced by the respective test case (which appear to be truncated):
$ uniq -c stack1
1 java.lang.StackOverflowError
1 at com.google.common.io.ByteSource$ByteArrayByteSource.openStream(ByteSource.java:574)
1 at com.google.common.io.MultiInputStream.advance(MultiInputStream.java:65)
1 at com.google.common.io.MultiInputStream.read(MultiInputStream.java:89)
1021 at com.google.common.io.MultiInputStream.read(MultiInputStream.java:90)
$ uniq -c stack2
1 java.lang.StackOverflowError
1 at com.google.common.io.MultiInputStream.close(MultiInputStream.java:52)
1 at com.google.common.io.MultiInputStream.advance(MultiInputStream.java:63)
1 at com.google.common.io.MultiInputStream.read(MultiInputStream.java:102)
1021 at com.google.common.io.MultiInputStream.read(MultiInputStream.java:103)