diff --git a/src/java.base/share/classes/java/lang/String.java b/src/java.base/share/classes/java/lang/String.java index 9dd912e5d0e..15b8e98369e 100644 --- a/src/java.base/share/classes/java/lang/String.java +++ b/src/java.base/share/classes/java/lang/String.java @@ -690,13 +690,10 @@ public final class String /* * Throws iae, instead of replacing, if malformed or unmappable. - * - * @param noShare - * {@code true} if the resulting string MUST NOT share the byte array, - * {@code false} if the byte array can be exclusively used to construct - * the string and is not modified or used for any other purpose. + * The byte array can be exclusively used to construct + * the string and is not modified or used for any other purpose. */ - static String newStringUTF8NoRepl(byte[] bytes, int offset, int length, boolean noShare) { + private static String newStringUTF8NoRepl(byte[] bytes, int offset, int length) { checkBoundsOffCount(offset, length, bytes.length); if (length == 0) { return ""; @@ -707,7 +704,7 @@ public final class String dp = StringCoding.countPositives(bytes, offset, length); int sl = offset + length; if (dp == length) { - if (noShare || length != bytes.length) { + if (length != bytes.length) { return new String(Arrays.copyOfRange(bytes, offset, offset + length), LATIN1); } else { return new String(bytes, LATIN1); @@ -774,6 +771,19 @@ public final class String return new String(StringLatin1.inflate(src, 0, src.length), UTF16); } + /** + * {@return a new {@code String} created using the given byte array that is + * encoded in specified charset} + *
+ * WARNING: The caller of this method is assumed to have relinquished + * and transferred the ownership of the byte array. It can thus be + * exclusively used to construct the {@code String}. + * + * @param src byte array containing encoded characters + * @param cs charset the byte array encoded in + * + * @throws CharacterCodingException for malformed input or unmappable characters + */ static String newStringNoRepl(byte[] src, Charset cs) throws CharacterCodingException { try { return newStringNoRepl1(src, cs); @@ -793,7 +803,7 @@ public final class String return ""; } if (cs == UTF_8.INSTANCE) { - return newStringUTF8NoRepl(src, 0, src.length, false); + return newStringUTF8NoRepl(src, 0, src.length); } if (cs == ISO_8859_1.INSTANCE) { if (COMPACT_STRINGS) diff --git a/src/java.base/share/classes/java/lang/System.java b/src/java.base/share/classes/java/lang/System.java index 4487c8415a1..f046ed4111a 100644 --- a/src/java.base/share/classes/java/lang/System.java +++ b/src/java.base/share/classes/java/lang/System.java @@ -2144,10 +2144,6 @@ public final class System { return String.getBytesNoRepl(s, cs); } - public String newStringUTF8NoRepl(byte[] bytes, int off, int len) { - return String.newStringUTF8NoRepl(bytes, off, len, true); - } - public byte[] getBytesUTF8NoRepl(String s) { return String.getBytesUTF8NoRepl(s); } diff --git a/src/java.base/share/classes/java/util/zip/ZipCoder.java b/src/java.base/share/classes/java/util/zip/ZipCoder.java index 0c3282e3518..8b812eba202 100644 --- a/src/java.base/share/classes/java/util/zip/ZipCoder.java +++ b/src/java.base/share/classes/java/util/zip/ZipCoder.java @@ -32,6 +32,7 @@ import java.nio.charset.CharsetDecoder; import java.nio.charset.CharsetEncoder; import java.nio.charset.CharacterCodingException; import java.nio.charset.CodingErrorAction; +import java.nio.charset.StandardCharsets; import java.util.Arrays; import jdk.internal.util.ArraysSupport; @@ -252,7 +253,13 @@ class ZipCoder { @Override String toString(byte[] ba, int off, int length) { - return JLA.newStringUTF8NoRepl(ba, off, length); + try { + // Copy subrange for exclusive use by the string being created + byte[] bytes = Arrays.copyOfRange(ba, off, off + length); + return JLA.uncheckedNewStringNoRepl(bytes, StandardCharsets.UTF_8); + } catch (CharacterCodingException cce) { + throw new IllegalArgumentException(cce); + } } @Override @@ -273,7 +280,7 @@ class ZipCoder { // shared and that decoder is not thread safe. // We use the JLA.newStringUTF8NoRepl variant to throw // exceptions eagerly when opening ZipFiles - return hash(JLA.newStringUTF8NoRepl(a, off, len)); + return hash(toString(a, off, len)); } int h = ArraysSupport.hashCodeOfUnsigned(a, off, len, 0); if (a[end - 1] != '/') { diff --git a/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java b/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java index 61b087b4872..aa5b6e438f5 100644 --- a/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java +++ b/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java @@ -363,16 +363,6 @@ public interface JavaLangAccess { */ byte[] uncheckedGetBytesNoRepl(String s, Charset cs) throws CharacterCodingException; - /** - * Returns a new string by decoding from the given UTF-8 bytes array. - * - * @param off the index of the first byte to decode - * @param len the number of bytes to decode - * @return the newly created string - * @throws IllegalArgumentException for malformed or unmappable bytes. - */ - String newStringUTF8NoRepl(byte[] bytes, int off, int len); - /** * Get the {@code char} at {@code index} in a {@code byte[]} in internal * UTF-16 representation.