diff --git a/src/java.base/share/classes/java/io/DataInputStream.java b/src/java.base/share/classes/java/io/DataInputStream.java index eab7a6e2f18..59377aca429 100644 --- a/src/java.base/share/classes/java/io/DataInputStream.java +++ b/src/java.base/share/classes/java/io/DataInputStream.java @@ -1,5 +1,6 @@ /* * Copyright (c) 1994, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, Alibaba Group Holding Limited. 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 @@ -25,8 +26,11 @@ package java.io; +import jdk.internal.access.JavaLangAccess; +import jdk.internal.access.SharedSecrets; import jdk.internal.util.ByteArray; +import java.nio.charset.StandardCharsets; import java.util.Objects; /** @@ -45,6 +49,7 @@ import java.util.Objects; * @since 1.0 */ public class DataInputStream extends FilterInputStream implements DataInput { + private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess(); private static final byte[] EMPTY_BYTE_ARRAY = new byte[0]; private static final char[] EMPTY_CHAR_ARRAY = new char[0]; @@ -573,18 +578,16 @@ loop: while (true) { */ public static final String readUTF(DataInput in) throws IOException { int utflen = in.readUnsignedShort(); - byte[] bytearr; - char[] chararr; + byte[] bytearr = null; if (in instanceof DataInputStream dis) { - if (dis.bytearr.length < utflen) { - dis.bytearr = new byte[utflen*2]; - dis.chararr = new char[utflen*2]; + if (dis.bytearr.length >= utflen) { + bytearr = dis.bytearr; } - chararr = dis.chararr; - bytearr = dis.bytearr; - } else { + } + boolean trusted = false; + if (bytearr == null) { bytearr = new byte[utflen]; - chararr = new char[utflen]; + trusted = true; } int c, char2, char3; @@ -592,12 +595,35 @@ loop: while (true) { int chararr_count=0; in.readFully(bytearr, 0, utflen); + int ascii = JLA.countPositives(bytearr, 0, utflen); + if (ascii == utflen) { + String str; + if (trusted) { + str = JLA.newStringNoRepl(bytearr, StandardCharsets.ISO_8859_1); + } else { + str = new String(bytearr, 0, utflen, StandardCharsets.ISO_8859_1); + } + return str; + } + if (trusted && in instanceof DataInputStream dis) { + dis.bytearr = bytearr; + trusted = false; + } - while (count < utflen) { - c = (int) bytearr[count] & 0xff; - if (c > 127) break; - count++; - chararr[chararr_count++]=(char)c; + char[] chararr; + if (in instanceof DataInputStream dis) { + if (dis.chararr.length < (utflen << 1)) { + dis.chararr = new char[utflen << 1]; + } + chararr = dis.chararr; + } else { + chararr = new char[utflen]; + } + + if (ascii != 0) { + JLA.inflateBytesToChars(bytearr, 0, chararr, 0, ascii); + count += ascii; + chararr_count += ascii; } while (count < utflen) {