8267529: StringJoiner can create a String that breaks String::equals

Reviewed-by: naoto
This commit is contained in:
Claes Redestad 2021-05-27 23:09:22 +00:00
parent 7f52c50ba3
commit 95b1fa7a88
2 changed files with 20 additions and 4 deletions

View File

@ -3239,8 +3239,12 @@ public final class String
*/
@ForceInline
static String join(String prefix, String suffix, String delimiter, String[] elements, int size) {
int icoder = prefix.coder() | suffix.coder() | delimiter.coder();
long len = (long) prefix.length() + suffix.length() + (long) Math.max(0, size - 1) * delimiter.length();
int icoder = prefix.coder() | suffix.coder();
long len = (long) prefix.length() + suffix.length();
if (size > 1) { // when there are more than one element, size - 1 delimiters will be emitted
len += (long) (size - 1) * delimiter.length();
icoder |= delimiter.coder();
}
// assert len > 0L; // max: (long) Integer.MAX_VALUE << 32
// following loop wil add max: (long) Integer.MAX_VALUE * Integer.MAX_VALUE to len
// so len can overflow at most once

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -21,13 +21,15 @@
* questions.
*/
/**
* @test @bug 5015163
* @test
* @bug 5015163 8267529
* @summary test String merge/join that is the inverse of String.split()
* @run testng StringJoinTest
* @author Jim Gish
*/
import java.util.ArrayList;
import java.util.List;
import java.util.StringJoiner;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
@ -111,4 +113,14 @@ public class StringJoinTest {
public void testJoinNullDelimiter() {
String.join(null, JIM, JOHN);
}
public void testIgnoreDelimiterCoderJoin() {
// 8267529: Ensure that joining zero or one latin-1 Strings with a UTF-16
// delimiter produce a String with a latin-1 coder, since the delimiter
// is not added.
assertEquals("", new StringJoiner("\u2013").toString());
assertEquals("foo", new StringJoiner("\u2013").add("foo").toString());
assertEquals("", String.join("\u2013"));
assertEquals("foo", String.join("\u2013", "foo"));
}
}