8230743: StringJoiner does not handle too large strings correctly
Reviewed-by: rriggs, psandoz, martin
This commit is contained in:
parent
cb960ee7b5
commit
4de4200652
@ -125,6 +125,7 @@ public final class StringJoiner {
|
||||
this.prefix = prefix.toString();
|
||||
this.delimiter = delimiter.toString();
|
||||
this.suffix = suffix.toString();
|
||||
checkAddLength(0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -202,13 +203,22 @@ public final class StringJoiner {
|
||||
} else {
|
||||
if (size == elts.length)
|
||||
elts = Arrays.copyOf(elts, 2 * size);
|
||||
len += delimiter.length();
|
||||
len = checkAddLength(len, delimiter.length());
|
||||
}
|
||||
len += elt.length();
|
||||
len = checkAddLength(len, elt.length());
|
||||
elts[size++] = elt;
|
||||
return this;
|
||||
}
|
||||
|
||||
private int checkAddLength(int oldLen, int inc) {
|
||||
long newLen = (long)oldLen + (long)inc;
|
||||
long tmpLen = newLen + (long)prefix.length() + (long)suffix.length();
|
||||
if (tmpLen != (int)tmpLen) {
|
||||
throw new OutOfMemoryError("Requested array size exceeds VM limit");
|
||||
}
|
||||
return (int)newLen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the contents of the given {@code StringJoiner} without prefix and
|
||||
* suffix as the next element if it is non-empty. If the given {@code
|
||||
|
@ -25,12 +25,14 @@
|
||||
* @test
|
||||
* @bug 8017231 8020977 8054221
|
||||
* @summary test StringJoiner::merge
|
||||
* @modules java.base/jdk.internal.util
|
||||
* @run testng MergeTest
|
||||
*/
|
||||
|
||||
import java.util.StringJoiner;
|
||||
import java.util.stream.Stream;
|
||||
import org.testng.annotations.Test;
|
||||
import static jdk.internal.util.ArraysSupport.MAX_ARRAY_LENGTH;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.fail;
|
||||
|
||||
@ -167,4 +169,19 @@ public class MergeTest {
|
||||
assertEquals(sj.merge(sj).toString(), fixes.pre0 + "a,b,a,b,a,b,a,b" + fixes.suf0);
|
||||
});
|
||||
}
|
||||
|
||||
public void OOM() {
|
||||
String maxString = "*".repeat(MAX_ARRAY_LENGTH);
|
||||
|
||||
try {
|
||||
StringJoiner sj1 = new StringJoiner("", "", "");
|
||||
sj1.add(maxString);
|
||||
StringJoiner sj2 = new StringJoiner("", "", "");
|
||||
sj2.add(maxString);
|
||||
sj1.merge(sj2);
|
||||
fail("Should have thrown OutOfMemoryError");
|
||||
} catch (OutOfMemoryError ex) {
|
||||
// okay
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,13 +24,17 @@
|
||||
* @test
|
||||
* @bug 5015163 7172553
|
||||
* @summary tests StringJoinerTest
|
||||
* @modules java.base/jdk.internal.util
|
||||
* @run testng StringJoinerTest
|
||||
* @author Jim Gish
|
||||
*/
|
||||
import java.util.ArrayList;
|
||||
import java.util.StringJoiner;
|
||||
import org.testng.annotations.Test;
|
||||
import static jdk.internal.util.ArraysSupport.MAX_ARRAY_LENGTH;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.fail;
|
||||
|
||||
|
||||
@Test(groups = {"unit","string","util","libs"})
|
||||
public class StringJoinerTest {
|
||||
@ -320,5 +324,49 @@ public class StringJoinerTest {
|
||||
testCombos(",", "", ">");
|
||||
testCombos(",", "<", ">");
|
||||
}
|
||||
|
||||
public void OOM1() {
|
||||
String maxString = "*".repeat(MAX_ARRAY_LENGTH);
|
||||
|
||||
try {
|
||||
new StringJoiner(maxString, maxString, maxString).toString();
|
||||
fail("Should have thrown OutOfMemoryError");
|
||||
} catch (OutOfMemoryError ex) {
|
||||
// okay
|
||||
}
|
||||
}
|
||||
|
||||
public void OOM2() {
|
||||
String maxString = "*".repeat(MAX_ARRAY_LENGTH);
|
||||
|
||||
try {
|
||||
new StringJoiner(maxString, maxString, "").toString();
|
||||
fail("Should have thrown OutOfMemoryError");
|
||||
} catch (OutOfMemoryError ex) {
|
||||
// okay
|
||||
}
|
||||
}
|
||||
|
||||
public void OOM3() {
|
||||
String maxString = "*".repeat(MAX_ARRAY_LENGTH);
|
||||
|
||||
try {
|
||||
new StringJoiner(maxString, "", maxString).toString();
|
||||
fail("Should have thrown OutOfMemoryError");
|
||||
} catch (OutOfMemoryError ex) {
|
||||
// okay
|
||||
}
|
||||
}
|
||||
|
||||
public void OOM4() {
|
||||
String maxString = "*".repeat(MAX_ARRAY_LENGTH);
|
||||
|
||||
try {
|
||||
new StringJoiner("", maxString, maxString).toString();
|
||||
fail("Should have thrown OutOfMemoryError");
|
||||
} catch (OutOfMemoryError ex) {
|
||||
// okay
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user