src/java.base/share/classes/java/lang/constant/ConstantUtils.java
author vromero
Wed, 09 Jan 2019 08:07:23 -0500
changeset 53224 bae765528fcc
parent 53019 4ddd3c410a85
permissions -rw-r--r--
8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec Reviewed-by: goetz
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
52914
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
     1
/*
53224
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
     2
 * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
52914
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
     4
 *
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    10
 *
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    15
 * accompanied this code).
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    16
 *
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    20
 *
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    23
 * questions.
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    24
 */
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    25
package java.lang.constant;
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    26
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    27
import java.util.ArrayList;
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    28
import java.util.List;
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    29
import java.util.Set;
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    30
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    31
import static java.util.Objects.requireNonNull;
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    32
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    33
/**
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    34
 * Helper methods for the implementation of {@code java.lang.constant}.
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    35
 */
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    36
class ConstantUtils {
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    37
    /** an empty constant descriptor */
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    38
    public static final ConstantDesc[] EMPTY_CONSTANTDESC = new ConstantDesc[0];
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    39
    static final Constable[] EMPTY_CONSTABLE = new Constable[0];
53019
4ddd3c410a85 8215300: additional changes to constants API
vromero
parents: 52914
diff changeset
    40
    static final int MAX_ARRAY_TYPE_DESC_DIMENSIONS = 255;
52914
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    41
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    42
    private static final Set<String> pointyNames = Set.of("<init>", "<clinit>");
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    43
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    44
    /**
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    45
     * Validates the correctness of a binary class name. In particular checks for the presence of
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    46
     * invalid characters in the name.
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    47
     *
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    48
     * @param name the class name
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    49
     * @return the class name passed if valid
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    50
     * @throws IllegalArgumentException if the class name is invalid
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    51
     */
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    52
    static String validateBinaryClassName(String name) {
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    53
        for (int i=0; i<name.length(); i++) {
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    54
            char ch = name.charAt(i);
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    55
            if (ch == ';' || ch == '[' || ch == '/')
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    56
                throw new IllegalArgumentException("Invalid class name: " + name);
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    57
        }
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    58
        return name;
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    59
    }
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    60
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    61
    /**
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    62
     * Validates a member name
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    63
     *
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    64
     * @param name the name of the member
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    65
     * @return the name passed if valid
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    66
     * @throws IllegalArgumentException if the member name is invalid
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    67
     */
53224
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
    68
    public static String validateMemberName(String name, boolean method) {
52914
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    69
        requireNonNull(name);
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    70
        if (name.length() == 0)
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    71
            throw new IllegalArgumentException("zero-length member name");
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    72
        for (int i=0; i<name.length(); i++) {
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    73
            char ch = name.charAt(i);
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    74
            if (ch == '.' || ch == ';' || ch == '[' || ch == '/')
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    75
                throw new IllegalArgumentException("Invalid member name: " + name);
53224
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
    76
            if (method && (ch == '<' || ch == '>')) {
52914
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    77
                if (!pointyNames.contains(name))
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    78
                    throw new IllegalArgumentException("Invalid member name: " + name);
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    79
            }
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    80
        }
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    81
        return name;
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    82
    }
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    83
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    84
    static void validateClassOrInterface(ClassDesc classDesc) {
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    85
        if (!classDesc.isClassOrInterface())
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    86
            throw new IllegalArgumentException("not a class or interface type: " + classDesc);
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    87
    }
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    88
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    89
    static int arrayDepth(String descriptorString) {
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    90
        int depth = 0;
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    91
        while (descriptorString.charAt(depth) == '[')
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    92
            depth++;
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    93
        return depth;
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    94
    }
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    95
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    96
    static String binaryToInternal(String name) {
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    97
        return name.replace('.', '/');
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    98
    }
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
    99
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   100
    static String internalToBinary(String name) {
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   101
        return name.replace('/', '.');
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   102
    }
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   103
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   104
    static String dropLastChar(String s) {
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   105
        return s.substring(0, s.length() - 1);
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   106
    }
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   107
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   108
    static String dropFirstAndLastChar(String s) {
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   109
        return s.substring(1, s.length() - 1);
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   110
    }
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   111
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   112
    /**
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   113
     * Parses a method descriptor string, and return a list of field descriptor
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   114
     * strings, return type first, then parameter types
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   115
     *
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   116
     * @param descriptor the descriptor string
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   117
     * @return the list of types
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   118
     * @throws IllegalArgumentException if the descriptor string is not valid
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   119
     */
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   120
    static List<String> parseMethodDescriptor(String descriptor) {
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   121
        int cur = 0, end = descriptor.length();
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   122
        ArrayList<String> ptypes = new ArrayList<>();
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   123
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   124
        if (cur >= end || descriptor.charAt(cur) != '(')
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   125
            throw new IllegalArgumentException("Bad method descriptor: " + descriptor);
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   126
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   127
        ++cur;  // skip '('
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   128
        while (cur < end && descriptor.charAt(cur) != ')') {
53224
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   129
            int len = skipOverFieldSignature(descriptor, cur, end, false);
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   130
            if (len == 0)
52914
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   131
                throw new IllegalArgumentException("Bad method descriptor: " + descriptor);
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   132
            ptypes.add(descriptor.substring(cur, cur + len));
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   133
            cur += len;
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   134
        }
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   135
        if (cur >= end)
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   136
            throw new IllegalArgumentException("Bad method descriptor: " + descriptor);
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   137
        ++cur;  // skip ')'
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   138
53224
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   139
        int rLen = skipOverFieldSignature(descriptor, cur, end, true);
52914
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   140
        if (rLen == 0 || cur + rLen != end)
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   141
            throw new IllegalArgumentException("Bad method descriptor: " + descriptor);
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   142
        ptypes.add(0, descriptor.substring(cur, cur + rLen));
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   143
        return ptypes;
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   144
    }
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   145
53224
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   146
    private static final char JVM_SIGNATURE_ARRAY = '[';
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   147
    private static final char JVM_SIGNATURE_BYTE = 'B';
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   148
    private static final char JVM_SIGNATURE_CHAR = 'C';
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   149
    private static final char JVM_SIGNATURE_CLASS = 'L';
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   150
    private static final char JVM_SIGNATURE_ENDCLASS = ';';
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   151
    private static final char JVM_SIGNATURE_ENUM = 'E';
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   152
    private static final char JVM_SIGNATURE_FLOAT = 'F';
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   153
    private static final char JVM_SIGNATURE_DOUBLE = 'D';
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   154
    private static final char JVM_SIGNATURE_FUNC = '(';
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   155
    private static final char JVM_SIGNATURE_ENDFUNC = ')';
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   156
    private static final char JVM_SIGNATURE_INT = 'I';
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   157
    private static final char JVM_SIGNATURE_LONG = 'J';
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   158
    private static final char JVM_SIGNATURE_SHORT = 'S';
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   159
    private static final char JVM_SIGNATURE_VOID = 'V';
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   160
    private static final char JVM_SIGNATURE_BOOLEAN = 'Z';
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   161
52914
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   162
    /**
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   163
     * Validates that the characters at [start, end) within the provided string
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   164
     * describe a valid field type descriptor.
53224
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   165
     * @param descriptor the descriptor string
52914
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   166
     * @param start the starting index into the string
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   167
     * @param end the ending index within the string
53224
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   168
     * @param voidOK is void acceptable?
52914
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   169
     * @return the length of the descriptor, or 0 if it is not a descriptor
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   170
     * @throws IllegalArgumentException if the descriptor string is not valid
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   171
     */
53224
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   172
    @SuppressWarnings("fallthrough")
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   173
    static int skipOverFieldSignature(String descriptor, int start, int end, boolean voidOK) {
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   174
        int arrayDim = 0;
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   175
        int index = start;
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   176
        while (index < end) {
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   177
            switch (descriptor.charAt(index)) {
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   178
                case JVM_SIGNATURE_VOID: if (!voidOK) { return index; }
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   179
                case JVM_SIGNATURE_BOOLEAN:
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   180
                case JVM_SIGNATURE_BYTE:
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   181
                case JVM_SIGNATURE_CHAR:
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   182
                case JVM_SIGNATURE_SHORT:
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   183
                case JVM_SIGNATURE_INT:
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   184
                case JVM_SIGNATURE_FLOAT:
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   185
                case JVM_SIGNATURE_LONG:
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   186
                case JVM_SIGNATURE_DOUBLE:
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   187
                    return index - start + 1;
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   188
                case JVM_SIGNATURE_CLASS:
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   189
                    // Skip leading 'L' and ignore first appearance of ';'
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   190
                    index++;
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   191
                    int indexOfSemi = descriptor.indexOf(';', index);
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   192
                    if (indexOfSemi != -1) {
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   193
                        String unqualifiedName = descriptor.substring(index, indexOfSemi);
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   194
                        boolean legal = verifyUnqualifiedClassName(unqualifiedName);
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   195
                        if (!legal) {
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   196
                            return 0;
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   197
                        }
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   198
                        return index - start + unqualifiedName.length() + 1;
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   199
                    }
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   200
                    return 0;
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   201
                case JVM_SIGNATURE_ARRAY:
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   202
                    arrayDim++;
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   203
                    if (arrayDim > MAX_ARRAY_TYPE_DESC_DIMENSIONS) {
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   204
                        throw new IllegalArgumentException(String.format("Cannot create an array type descriptor with more than %d dimensions",
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   205
                                ConstantUtils.MAX_ARRAY_TYPE_DESC_DIMENSIONS));
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   206
                    }
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   207
                    // The rest of what's there better be a legal descriptor
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   208
                    index++;
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   209
                    voidOK = false;
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   210
                    break;
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   211
                default:
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   212
                    return 0;
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   213
            }
52914
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   214
        }
53224
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   215
        return 0;
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   216
    }
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   217
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   218
    static boolean verifyUnqualifiedClassName(String name) {
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   219
        for (int index = 0; index < name.length(); index++) {
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   220
            char ch = name.charAt(index);
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   221
            if (ch < 128) {
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   222
                if (ch == '.' || ch == ';' || ch == '[' ) {
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   223
                    return false;   // do not permit '.', ';', or '['
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   224
                }
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   225
                if (ch == '/') {
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   226
                    // check for '//' or leading or trailing '/' which are not legal
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   227
                    // unqualified name must not be empty
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   228
                    if (index == 0 || index + 1 >= name.length() || name.charAt(index + 1) == '/') {
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   229
                        return false;
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   230
                    }
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   231
                }
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   232
            } else {
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   233
                index ++;
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   234
            }
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   235
        }
bae765528fcc 8215510: j.l.c.ClassDesc is accepting descriptors not allowed by the spec
vromero
parents: 53019
diff changeset
   236
        return true;
52914
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   237
    }
4fa75d8ad418 8210031: implementation for JVM Constants API
vromero
parents:
diff changeset
   238
}