RFR: 8298033: Character.codePointAt(char[], int, int) doesn't do JavaDoc-specified check

Sergey Tsypanov stsypanov at openjdk.org
Fri Dec 2 15:14:40 UTC 2022


On Fri, 2 Dec 2022 12:44:18 GMT, Sergey Tsypanov <stsypanov at openjdk.org> wrote:

> I found out that this code
> 
> public class Main {
>     public static void main(String[] args) {
>         String s = "Hello world!";
>         char[] chars = s.toCharArray();
>         int point = Character.codePointAt(chars, -1, 1);
>     }
> }
> 
> throws `ArrayIndexOutOfBoundsException` instead of JavaDoc-specified `IndexOutOfBoundsException`: 
> 
> Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index -1 out of bounds for length 12
> 	at java.base/java.lang.Character.codePointAtImpl(Character.java:9254)
> 	at java.base/java.lang.Character.codePointAt(Character.java:9249)
> 	at org.example.Main.main(Main.java:7)
> 
> and the method doesn't check whether `index` parameter is negative:
> 
> public static int codePointAt(char[] a, int index, int limit) {
>     if (index >= limit || limit < 0 || limit > a.length) {
>         throw new IndexOutOfBoundsException();
>     }
>     return codePointAtImpl(a, index, limit);
> }
> 
> I suggest to check the `index` parameter explicitly instead of relying on AIOOBE thrown from accessing the array with negative index.

I think the only way to do this is to change

private static void callCodePoint(boolean isAt, char[] a, int index, int limit,
                                  Class expectedException) {
    try {
        int c = isAt ? Character.codePointAt(a, index, limit)
                     : Character.codePointBefore(a, index, limit);
    } catch (Exception e) {
        if (expectedException.isInstance(e)) { // <---
            return;
        }
        throw new RuntimeException("Unspecified exception", e);
    }
    throw new RuntimeException("codePoint" + (isAt ? "At" : "Before")
                               + " didn't throw " + expectedException.getName());
}

to 

private static void callCodePoint(boolean isAt, char[] a, int index, int limit,
                                  Class expectedException) {
    try {
        int c = isAt ? Character.codePointAt(a, index, limit)
                     : Character.codePointBefore(a, index, limit);
    } catch (Exception e) {
        if (expectedException.getClass() == e.getClass()) { // <---
            return;
        }
        throw new RuntimeException("Unspecified exception", e);
    }
    throw new RuntimeException("codePoint" + (isAt ? "At" : "Before")
                               + " didn't throw " + expectedException.getName());
}

i.e. check exception type strictly. What do you think?

-------------

PR: https://git.openjdk.org/jdk/pull/11480


More information about the core-libs-dev mailing list