Skip to content

Commit 6926849

Browse files
committed
[IO-764] IOUtils.write() throws
OutOfMemoryError/NegativeArraySizeException while writing big strings. - Better test than in PR #343 that validates the output size.
1 parent 05d531a commit 6926849

1 file changed

Lines changed: 35 additions & 0 deletions

File tree

src/test/java/org/apache/commons/io/IOUtilsTest.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,12 @@
6363
import org.apache.commons.io.input.NullInputStream;
6464
import org.apache.commons.io.input.StringInputStream;
6565
import org.apache.commons.io.output.AppendableWriter;
66+
import org.apache.commons.io.output.CountingOutputStream;
6667
import org.apache.commons.io.output.NullOutputStream;
6768
import org.apache.commons.io.output.StringBuilderWriter;
6869
import org.apache.commons.io.test.TestUtils;
6970
import org.apache.commons.io.test.ThrowOnCloseReader;
71+
import org.apache.commons.lang3.StringUtils;
7072
import org.junit.jupiter.api.BeforeEach;
7173
import org.junit.jupiter.api.Disabled;
7274
import org.junit.jupiter.api.Test;
@@ -319,6 +321,39 @@ public void testAsWriterStringBuilder() {
319321
assertSame(w, IOUtils.writer(w));
320322
}
321323

324+
/**
325+
* IO-764 IOUtils.write() throws NegativeArraySizeException while writing big strings.
326+
* <pre>
327+
* java.lang.OutOfMemoryError: Java heap space
328+
* at java.lang.StringCoding.encode(StringCoding.java:350)
329+
* at java.lang.String.getBytes(String.java:941)
330+
* at org.apache.commons.io.IOUtils.write(IOUtils.java:3367)
331+
* at org.apache.commons.io.IOUtilsTest.testBigString(IOUtilsTest.java:1659)
332+
* </pre>
333+
*/
334+
@Test
335+
public void testBigString() throws IOException {
336+
// 3_000_000 is a size that we can allocate for the test string with Java 8 on the command line as:
337+
// mvn clean test -Dtest=IOUtilsTest -DtestBigString=3000000
338+
// 6_000_000 failed with the above
339+
//
340+
// TODO Can we mock the test string for this test to pretend to be larger?
341+
// Mocking the length seems simple but how about the data?
342+
final int repeat = Integer.getInteger("testBigString", 3_000_000);
343+
String data;
344+
try {
345+
data = StringUtils.repeat("\uD83D", repeat);
346+
} catch (OutOfMemoryError e) {
347+
System.err.printf("Don't fail the test if we cannot build the fixture, just log, fixture size = %,d%n.", repeat);
348+
e.printStackTrace();
349+
return;
350+
}
351+
try (CountingOutputStream os = new CountingOutputStream(NullOutputStream.INSTANCE)) {
352+
IOUtils.write(data, os, StandardCharsets.UTF_8);
353+
assertEquals(repeat, os.getByteCount());
354+
}
355+
}
356+
322357
@Test
323358
public void testClose() {
324359
assertDoesNotThrow(() -> IOUtils.close((Closeable) null));

0 commit comments

Comments
 (0)