< prev index next >

src/java.base/share/classes/java/lang/constant/ConstantUtils.java

Print this page

130             if (len == 0)
131                 throw new IllegalArgumentException("Bad method descriptor: " + descriptor);
132             ptypes.add(descriptor.substring(cur, cur + len));
133             cur += len;
134         }
135         if (cur >= end)
136             throw new IllegalArgumentException("Bad method descriptor: " + descriptor);
137         ++cur;  // skip ')'
138 
139         int rLen = skipOverFieldSignature(descriptor, cur, end, true);
140         if (rLen == 0 || cur + rLen != end)
141             throw new IllegalArgumentException("Bad method descriptor: " + descriptor);
142         ptypes.add(0, descriptor.substring(cur, cur + rLen));
143         return ptypes;
144     }
145 
146     private static final char JVM_SIGNATURE_ARRAY = '[';
147     private static final char JVM_SIGNATURE_BYTE = 'B';
148     private static final char JVM_SIGNATURE_CHAR = 'C';
149     private static final char JVM_SIGNATURE_CLASS = 'L';

150     private static final char JVM_SIGNATURE_ENDCLASS = ';';
151     private static final char JVM_SIGNATURE_ENUM = 'E';
152     private static final char JVM_SIGNATURE_FLOAT = 'F';
153     private static final char JVM_SIGNATURE_DOUBLE = 'D';
154     private static final char JVM_SIGNATURE_FUNC = '(';
155     private static final char JVM_SIGNATURE_ENDFUNC = ')';
156     private static final char JVM_SIGNATURE_INT = 'I';
157     private static final char JVM_SIGNATURE_LONG = 'J';
158     private static final char JVM_SIGNATURE_SHORT = 'S';
159     private static final char JVM_SIGNATURE_VOID = 'V';
160     private static final char JVM_SIGNATURE_BOOLEAN = 'Z';
161 
162     /**
163      * Validates that the characters at [start, end) within the provided string
164      * describe a valid field type descriptor.
165      * @param descriptor the descriptor string
166      * @param start the starting index into the string
167      * @param end the ending index within the string
168      * @param voidOK is void acceptable?
169      * @return the length of the descriptor, or 0 if it is not a descriptor
170      * @throws IllegalArgumentException if the descriptor string is not valid
171      */
172     @SuppressWarnings("fallthrough")
173     static int skipOverFieldSignature(String descriptor, int start, int end, boolean voidOK) {
174         int arrayDim = 0;
175         int index = start;
176         while (index < end) {
177             switch (descriptor.charAt(index)) {
178                 case JVM_SIGNATURE_VOID: if (!voidOK) { return index; }
179                 case JVM_SIGNATURE_BOOLEAN:
180                 case JVM_SIGNATURE_BYTE:
181                 case JVM_SIGNATURE_CHAR:
182                 case JVM_SIGNATURE_SHORT:
183                 case JVM_SIGNATURE_INT:
184                 case JVM_SIGNATURE_FLOAT:
185                 case JVM_SIGNATURE_LONG:
186                 case JVM_SIGNATURE_DOUBLE:
187                     return index - start + 1;
188                 case JVM_SIGNATURE_CLASS:
189                     // Skip leading 'L' and ignore first appearance of ';'

190                     index++;
191                     int indexOfSemi = descriptor.indexOf(';', index);
192                     if (indexOfSemi != -1) {
193                         String unqualifiedName = descriptor.substring(index, indexOfSemi);
194                         boolean legal = verifyUnqualifiedClassName(unqualifiedName);
195                         if (!legal) {
196                             return 0;
197                         }
198                         return index - start + unqualifiedName.length() + 1;
199                     }
200                     return 0;
201                 case JVM_SIGNATURE_ARRAY:
202                     arrayDim++;
203                     if (arrayDim > MAX_ARRAY_TYPE_DESC_DIMENSIONS) {
204                         throw new IllegalArgumentException(String.format("Cannot create an array type descriptor with more than %d dimensions",
205                                 ConstantUtils.MAX_ARRAY_TYPE_DESC_DIMENSIONS));
206                     }
207                     // The rest of what's there better be a legal descriptor
208                     index++;
209                     voidOK = false;
210                     break;
211                 default:
212                     return 0;
213             }
214         }
215         return 0;
216     }
217 
























































218     static boolean verifyUnqualifiedClassName(String name) {
219         for (int index = 0; index < name.length(); index++) {
220             char ch = name.charAt(index);
221             if (ch < 128) {
222                 if (ch == '.' || ch == ';' || ch == '[' ) {
223                     return false;   // do not permit '.', ';', or '['
224                 }
225                 if (ch == '/') {
226                     // check for '//' or leading or trailing '/' which are not legal
227                     // unqualified name must not be empty
228                     if (index == 0 || index + 1 >= name.length() || name.charAt(index + 1) == '/') {
229                         return false;
230                     }
231                 }
232             } else {
233                 index ++;
234             }
235         }
236         return true;
237     }

130             if (len == 0)
131                 throw new IllegalArgumentException("Bad method descriptor: " + descriptor);
132             ptypes.add(descriptor.substring(cur, cur + len));
133             cur += len;
134         }
135         if (cur >= end)
136             throw new IllegalArgumentException("Bad method descriptor: " + descriptor);
137         ++cur;  // skip ')'
138 
139         int rLen = skipOverFieldSignature(descriptor, cur, end, true);
140         if (rLen == 0 || cur + rLen != end)
141             throw new IllegalArgumentException("Bad method descriptor: " + descriptor);
142         ptypes.add(0, descriptor.substring(cur, cur + rLen));
143         return ptypes;
144     }
145 
146     private static final char JVM_SIGNATURE_ARRAY = '[';
147     private static final char JVM_SIGNATURE_BYTE = 'B';
148     private static final char JVM_SIGNATURE_CHAR = 'C';
149     private static final char JVM_SIGNATURE_CLASS = 'L';
150     private static final char JVM_SIGNATURE_VALUE_TYPE = 'Q';
151     private static final char JVM_SIGNATURE_ENDCLASS = ';';
152     private static final char JVM_SIGNATURE_ENUM = 'E';
153     private static final char JVM_SIGNATURE_FLOAT = 'F';
154     private static final char JVM_SIGNATURE_DOUBLE = 'D';
155     private static final char JVM_SIGNATURE_FUNC = '(';
156     private static final char JVM_SIGNATURE_ENDFUNC = ')';
157     private static final char JVM_SIGNATURE_INT = 'I';
158     private static final char JVM_SIGNATURE_LONG = 'J';
159     private static final char JVM_SIGNATURE_SHORT = 'S';
160     private static final char JVM_SIGNATURE_VOID = 'V';
161     private static final char JVM_SIGNATURE_BOOLEAN = 'Z';
162 
163     /**
164      * Validates that the characters at [start, end) within the provided string
165      * describe a valid field type descriptor.
166      * @param descriptor the descriptor string
167      * @param start the starting index into the string
168      * @param end the ending index within the string
169      * @param voidOK is void acceptable?
170      * @return the length of the descriptor, or 0 if it is not a descriptor
171      * @throws IllegalArgumentException if the descriptor string is not valid
172      */
173     @SuppressWarnings("fallthrough")
174     static int skipOverFieldSignature(String descriptor, int start, int end, boolean voidOK) {
175         int arrayDim = 0;
176         int index = start;
177         while (index < end) {
178             switch (descriptor.charAt(index)) {
179                 case JVM_SIGNATURE_VOID: if (!voidOK) { return index; }
180                 case JVM_SIGNATURE_BOOLEAN:
181                 case JVM_SIGNATURE_BYTE:
182                 case JVM_SIGNATURE_CHAR:
183                 case JVM_SIGNATURE_SHORT:
184                 case JVM_SIGNATURE_INT:
185                 case JVM_SIGNATURE_FLOAT:
186                 case JVM_SIGNATURE_LONG:
187                 case JVM_SIGNATURE_DOUBLE:
188                     return index - start + 1;
189                 case JVM_SIGNATURE_CLASS:
190                 case JVM_SIGNATURE_VALUE_TYPE:
191                     // Skip leading 'L' or 'Q' and ignore first appearance of ';'
192                     index++;
193                     int indexOfSemi = descriptor.indexOf(';', index);
194                     if (indexOfSemi != -1) {
195                         String unqualifiedName = descriptor.substring(index, indexOfSemi);
196                         boolean legal = verifyUnqualifiedClassName(unqualifiedName);
197                         if (!legal) {
198                             return 0;
199                         }
200                         return index - start + unqualifiedName.length() + 1;
201                     }
202                     return 0;
203                 case JVM_SIGNATURE_ARRAY:
204                     arrayDim++;
205                     if (arrayDim > MAX_ARRAY_TYPE_DESC_DIMENSIONS) {
206                         throw new IllegalArgumentException(String.format("Cannot create an array type descriptor with more than %d dimensions",
207                                 ConstantUtils.MAX_ARRAY_TYPE_DESC_DIMENSIONS));
208                     }
209                     // The rest of what's there better be a legal descriptor
210                     index++;
211                     voidOK = false;
212                     break;
213                 default:
214                     return 0;
215             }
216         }
217         return 0;
218     }
219 
220     /**
221      * Returns the basic type of the given descriptor.  If {@code verifyClassName}
222      * is true, then this method will validate that the characters at [start, end)
223      * within the given string describe a valid field type descriptor.
224      *
225      * @return the character represents the basic type that the descriptor string
226      * references
227      * @throws IllegalArgumentException if the descriptor string is not valid
228      */
229     static char basicType(String descriptor, int start, int end, boolean verifyClassName) {
230         int arrayDim = 0;
231         int index = start;
232         while (index < end) {
233             char c = descriptor.charAt(index);
234             switch (c) {
235                 case JVM_SIGNATURE_VOID:
236                 case JVM_SIGNATURE_BOOLEAN:
237                 case JVM_SIGNATURE_BYTE:
238                 case JVM_SIGNATURE_CHAR:
239                 case JVM_SIGNATURE_SHORT:
240                 case JVM_SIGNATURE_INT:
241                 case JVM_SIGNATURE_FLOAT:
242                 case JVM_SIGNATURE_LONG:
243                 case JVM_SIGNATURE_DOUBLE:
244                     return c;
245                 case JVM_SIGNATURE_CLASS:
246                 case JVM_SIGNATURE_VALUE_TYPE:
247                     index++;
248                     int indexOfSemi = descriptor.indexOf(';', index);
249                     if (indexOfSemi != -1) {
250                         if (verifyClassName) {
251                             String unqualifiedName = descriptor.substring(index, indexOfSemi);
252                             boolean legal = verifyUnqualifiedClassName(unqualifiedName);
253                             if (!legal) {
254                                 throw new IllegalArgumentException(String.format("not a valid type descriptor: %s", descriptor));
255                             }
256                         }
257                         return c;
258                     }
259                     throw new IllegalArgumentException(String.format("not a valid type descriptor: %s", descriptor));
260                 case JVM_SIGNATURE_ARRAY:
261                     arrayDim++;
262                     if (arrayDim > MAX_ARRAY_TYPE_DESC_DIMENSIONS) {
263                         throw new IllegalArgumentException(String.format("Cannot create an array type descriptor with more than %d dimensions",
264                                 ConstantUtils.MAX_ARRAY_TYPE_DESC_DIMENSIONS));
265                     }
266                     // The rest of what's there better be a legal descriptor
267                     index++;
268                     break;
269                 default:
270                     throw new IllegalArgumentException(String.format("not a valid type descriptor: %s", descriptor));
271             }
272         }
273         throw new IllegalArgumentException(String.format("not a valid type descriptor: %s", descriptor));
274     }
275 
276     static boolean verifyUnqualifiedClassName(String name) {
277         for (int index = 0; index < name.length(); index++) {
278             char ch = name.charAt(index);
279             if (ch < 128) {
280                 if (ch == '.' || ch == ';' || ch == '[' ) {
281                     return false;   // do not permit '.', ';', or '['
282                 }
283                 if (ch == '/') {
284                     // check for '//' or leading or trailing '/' which are not legal
285                     // unqualified name must not be empty
286                     if (index == 0 || index + 1 >= name.length() || name.charAt(index + 1) == '/') {
287                         return false;
288                     }
289                 }
290             } else {
291                 index ++;
292             }
293         }
294         return true;
295     }
< prev index next >