From fde5b16817c3263236993f2e8c2d2469610d99bd Mon Sep 17 00:00:00 2001 From: Aleksei Voitylov Date: Thu, 14 Dec 2023 14:39:04 +0000 Subject: [PATCH] 8321514: UTF16 string gets constructed incorrectly from codepoints if CompactStrings is not enabled Co-authored-by: Roger Riggs Reviewed-by: rriggs --- .../share/classes/java/lang/StringUTF16.java | 2 +- test/jdk/java/lang/String/Chars.java | 27 ++++++++++++++++++- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/java.base/share/classes/java/lang/StringUTF16.java b/src/java.base/share/classes/java/lang/StringUTF16.java index c202c6c2c68..b94b583962d 100644 --- a/src/java.base/share/classes/java/lang/StringUTF16.java +++ b/src/java.base/share/classes/java/lang/StringUTF16.java @@ -415,7 +415,7 @@ final class StringUTF16 { int n = computeCodePointSize(val, index, end); byte[] buf = newBytesFor(n); - return extractCodepoints(val, index, len, buf, 0); + return extractCodepoints(val, index, end, buf, 0); } public static byte[] toBytes(char c) { diff --git a/test/jdk/java/lang/String/Chars.java b/test/jdk/java/lang/String/Chars.java index 20cde9d003d..035a7a9de27 100644 --- a/test/jdk/java/lang/String/Chars.java +++ b/test/jdk/java/lang/String/Chars.java @@ -23,8 +23,10 @@ /* * @test - * @bug 8054307 8311906 + * @bug 8054307 8311906 8321514 * @summary test String chars() and codePoints() + * @run main/othervm -XX:+CompactStrings Chars + * @run main/othervm -XX:-CompactStrings Chars */ import java.util.Arrays; @@ -45,6 +47,7 @@ public class Chars { } testChars(cc, ccExp); testCharsSubrange(cc, ccExp); + testIntsSubrange(ccExp); testCPs(cc, cpExp); // bmp without surrogates @@ -72,6 +75,7 @@ public class Chars { cpExp = Arrays.copyOf(cpExp, k); testChars(cc, ccExp); testCharsSubrange(cc, ccExp); + testIntsSubrange(ccExp); testCPs(cc, cpExp); } } @@ -104,6 +108,27 @@ public class Chars { } } + static void testIntsSubrange(int[] expected) { + int[] offsets = { 7, 31 }; // offsets to test + int LENGTH = 13; + for (int i = 0; i < offsets.length; i++) { + int offset = Math.max(0, offsets[i]); // confine to the input array + int count = Math.min(LENGTH, expected.length - offset); + String str = new String(expected, offset, count); + int[] actual = str.chars().toArray(); + int errOffset = Arrays.mismatch(actual, 0, actual.length, + expected, offset, offset + count); + if (errOffset >= 0) { + System.err.printf("expected[%d] (%d) != actual[%d] (%d)%n", + offset + errOffset, expected[offset + errOffset], + errOffset, actual[errOffset]); + System.err.println("expected: " + Arrays.toString(expected)); + System.err.println("actual: " + Arrays.toString(actual)); + throw new RuntimeException("testIntsSubrange failed!"); + } + } + } + static void testCPs(char[] cc, int[] expected) { String str = new String(cc); if (!Arrays.equals(expected, str.codePoints().toArray())) {