Skip to content

8353197: Document preconditions for JavaLangAccess methods #24982

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 41 additions & 19 deletions src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,8 @@ public interface JavaLangAccess {

/**
* Count the number of leading positive bytes in the range.
* <p>
* <b>WARNING: This method does not perform any bound checks.</b>
*/
int countPositives(byte[] ba, int off, int len);

Expand All @@ -305,11 +307,12 @@ public interface JavaLangAccess {
int countNonZeroAscii(String s);

/**
* Constructs a new {@code String} by decoding the specified subarray of
* bytes using the specified {@linkplain java.nio.charset.Charset charset}.
*
* The caller of this method shall relinquish and transfer the ownership of
* the byte array to the callee since the later will not make a copy.
* Constructs a new {@code String} by decoding the specified byte array
* using the specified {@linkplain java.nio.charset.Charset charset}.
* <p>
* <b>WARNING: The caller of this method shall relinquish and transfer the
* ownership of the byte array to the callee</b>, since the later will not
* make a copy.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should add a note on why no copy is made - there may be multiple reads to the input array for decoding, so the input array must not be accessible by untrusted code, which can racily modify it. A side effect is that this array is simply reused if it's eligible to be the string content array, which is unfortunately abused in a few places in the JDK.

*
* @param bytes the byte array source
* @param cs the Charset
Expand All @@ -319,13 +322,14 @@ public interface JavaLangAccess {
String newStringNoRepl(byte[] bytes, Charset cs) throws CharacterCodingException;

/**
* Encode the given string into a sequence of bytes using the specified Charset.
*
* This method avoids copying the String's internal representation if the input
* is ASCII.
*
* This method throws CharacterCodingException instead of replacing when
* malformed input or unmappable characters are encountered.
* Encode the given string into a sequence of bytes using the specified
* {@linkplain java.nio.charset.Charset charset}.
* <p>
* <b>WARNING: This method return the {@code byte[]} backing the provided
* {@code String}, if the input is ASCII.</b>
* <p>
* This method throws {@code CharacterCodingException} instead of replacing
* when malformed input or unmappable characters are encountered.
*
* @param s the string to encode
* @param cs the charset
Expand All @@ -335,7 +339,7 @@ public interface JavaLangAccess {
byte[] getBytesNoRepl(String s, Charset cs) throws CharacterCodingException;

/**
* Returns a new string by decoding from the given utf8 bytes array.
* 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
Expand All @@ -345,8 +349,10 @@ public interface JavaLangAccess {
String newStringUTF8NoRepl(byte[] bytes, int off, int len);

/**
* Get the char at index in a byte[] in internal UTF-16 representation,
* with no bounds checks.
* Get the {@code char} at {@code index} in a {@code byte[]} in internal
* UTF-16 representation.
* <p>
* <b>WARNING: This method does not perform any bound checks.</b>
*
* @param bytes the UTF-16 encoded bytes
* @param index of the char to retrieve, 0 <= index < (bytes.length >> 1)
Expand All @@ -355,8 +361,10 @@ public interface JavaLangAccess {
char getUTF16Char(byte[] bytes, int index);

/**
* Put the char at index in a byte[] in internal UTF-16 representation,
* with no bounds checks.
* Put the {@code ch} at {@code index} in a {@code byte[]} in internal
* UTF-16 representation.
* <p>
* <b>WARNING: This method does not perform any bound checks.</b>
*
* @param bytes the UTF-16 encoded bytes
* @param index of the char to retrieve, 0 <= index < (bytes.length >> 1)
Expand All @@ -373,13 +381,18 @@ public interface JavaLangAccess {
byte[] getBytesUTF8NoRepl(String s);

/**
* Inflated copy from byte[] to char[], as defined by StringLatin1.inflate
* Inflated copy from {@code byte[]} to {@code char[]}, as defined by
* {@code StringLatin1.inflate}.
* <p>
* <b>WARNING: This method does not perform any bound checks.</b>
*/
void inflateBytesToChars(byte[] src, int srcOff, char[] dst, int dstOff, int len);

/**
* Decodes ASCII from the source byte array into the destination
* char array.
* <p>
* <b>WARNING: This method does not perform any bound checks.</b>
*
* @return the number of bytes successfully decoded, at most len
*/
Expand All @@ -399,7 +412,9 @@ public interface JavaLangAccess {
/**
* Encodes ASCII codepoints as possible from the source array into
* the destination byte array, assuming that the encoding is ASCII
* compatible
* compatible.
* <p>
* <b>WARNING: This method does not perform any bound checks.</b>
*
* @return the number of bytes successfully encoded, or 0 if none
*/
Expand Down Expand Up @@ -436,6 +451,13 @@ public interface JavaLangAccess {
*/
long stringConcatMix(long lengthCoder, char value);

/**
* Creates helper for string concatenation.
* <p>
* <b>WARNING: The caller of this method shall relinquish and transfer the
* ownership of the string array to the callee</b>, since the later will not
* make a copy.
*/
Object stringConcat1(String[] constants);

/**
Expand Down