@@ -137,6 +137,7 @@ static String dropFirstAndLastChar(String s) {
137
137
static List <String > parseMethodDescriptor (String descriptor ) {
138
138
int cur = 0 , end = descriptor .length ();
139
139
ArrayList <String > ptypes = new ArrayList <>();
140
+ ptypes .add (null ); //placeholder for return type
140
141
141
142
if (cur >= end || descriptor .charAt (cur ) != '(' )
142
143
throw new IllegalArgumentException ("Bad method descriptor: " + descriptor );
@@ -156,7 +157,7 @@ static List<String> parseMethodDescriptor(String descriptor) {
156
157
int rLen = skipOverFieldSignature (descriptor , cur , end , true );
157
158
if (rLen == 0 || cur + rLen != end )
158
159
throw new IllegalArgumentException ("Bad method descriptor: " + descriptor );
159
- ptypes .add (0 , descriptor .substring (cur , cur + rLen ));
160
+ ptypes .set (0 , descriptor .substring (cur , cur + rLen ));
160
161
return ptypes ;
161
162
}
162
163
@@ -203,16 +204,27 @@ static int skipOverFieldSignature(String descriptor, int start, int end, boolean
203
204
case JVM_SIGNATURE_DOUBLE :
204
205
return index - start + 1 ;
205
206
case JVM_SIGNATURE_CLASS :
206
- // Skip leading 'L' and ignore first appearance of ';'
207
- index ++;
208
- int indexOfSemi = descriptor .indexOf (';' , index );
209
- if (indexOfSemi != -1 ) {
210
- String unqualifiedName = descriptor .substring (index , indexOfSemi );
211
- boolean legal = verifyUnqualifiedClassName (unqualifiedName );
212
- if (!legal ) {
213
- return 0 ;
207
+ // state variable for detection of illegal states, such as:
208
+ // empty unqualified name, '//', leading '/', or trailing '/'
209
+ boolean legal = false ;
210
+ while (++index < end ) {
211
+ switch (descriptor .charAt (index )) {
212
+ case ';' -> {
213
+ // illegal state on parser exit indicates empty unqualified name or trailing '/'
214
+ return legal ? index - start + 1 : 0 ;
215
+ }
216
+ case '.' , '[' -> {
217
+ // do not permit '.' or '['
218
+ return 0 ;
219
+ }
220
+ case '/' -> {
221
+ // illegal state when received '/' indicates '//' or leading '/'
222
+ if (!legal ) return 0 ;
223
+ legal = false ;
224
+ }
225
+ default ->
226
+ legal = true ;
214
227
}
215
- return index - start + unqualifiedName .length () + 1 ;
216
228
}
217
229
return 0 ;
218
230
case JVM_SIGNATURE_ARRAY :
@@ -231,25 +243,4 @@ static int skipOverFieldSignature(String descriptor, int start, int end, boolean
231
243
}
232
244
return 0 ;
233
245
}
234
-
235
- static boolean verifyUnqualifiedClassName (String name ) {
236
- for (int index = 0 ; index < name .length (); index ++) {
237
- char ch = name .charAt (index );
238
- if (ch < 128 ) {
239
- if (ch == '.' || ch == ';' || ch == '[' ) {
240
- return false ; // do not permit '.', ';', or '['
241
- }
242
- if (ch == '/' ) {
243
- // check for '//' or leading or trailing '/' which are not legal
244
- // unqualified name must not be empty
245
- if (index == 0 || index + 1 >= name .length () || name .charAt (index + 1 ) == '/' ) {
246
- return false ;
247
- }
248
- }
249
- } else {
250
- index ++;
251
- }
252
- }
253
- return true ;
254
- }
255
246
}
0 commit comments