blob: d9a880f09707a7e6a8376aed94dd036367a1698c [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2002 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26/* This file was generated AUTOMATICALLY from a template file Wed Jun 17 10:43:47 PDT 1998 */
27
28/*-
29 * code for verifying the date in a ClassClass structure for internal
30 * consistency.
31 */
32
33#include <ctype.h>
34
35#include "oobj.h"
36#include "interpreter.h"
37#include "bool.h"
38#include "utf.h"
39#include "tree.h"
40#include "sys_api.h"
41
42extern bool_t verify_class_codes(ClassClass *cb);
43
44static bool_t verify_constant_pool(ClassClass *cb);
45
46static bool_t is_legal_fieldname(ClassClass *cb, char *name, int type);
47static bool_t is_legal_method_signature(ClassClass *cb, char *name, char *signature);
48static bool_t is_legal_field_signature(ClassClass *cb, char *name, char *signature);
49
50static char *skip_over_fieldname(char *name, bool_t slash_okay);
51static char *skip_over_field_signature(char *name, bool_t void_okay);
52
53static void CCerror (ClassClass *cb, char *format, ...);
54
55
56/* Argument for is_legal_fieldname */
57enum { LegalClass, LegalField, LegalMethod };
58
59
60
61
62bool_t
63VerifyClass(ClassClass *cb)
64{
65 bool_t result = TRUE;
66 struct methodblock *mb;
67 struct fieldblock *fb;
68 int i;
69 if (CCIs(cb, Verified))
70 return TRUE;
71 if (!verify_constant_pool(cb))
72 return FALSE;
73 /* Make sure all the method names and signatures are okay */
74 for (i = cbMethodsCount(cb), mb = cbMethods(cb); --i >= 0; mb++) {
75 char *name = mb->fb.name;
76 char *signature = mb->fb.signature;
77 if (! (is_legal_fieldname(cb, name, LegalMethod) &&
78 is_legal_method_signature(cb, name, signature)))
79 result = FALSE;
80 }
81 /* Make sure all the field names and signatures are okay */
82 for (i = cbFieldsCount(cb), fb = cbFields(cb); --i >= 0; fb++) {
83 if (! (is_legal_fieldname(cb, fb->name, LegalField) &&
84 is_legal_field_signature(cb, fb->name, fb->signature)))
85 result = FALSE;
86 }
87 /* Make sure we are not overriding any final methods or classes*/
88 if (cbIsInterface(cb)) {
89 struct methodblock *mb;
90 if ((cbSuperclass(cb) == NULL) ||
91 (cbSuperclass(cb) != classJavaLangObject)) {
92 CCerror(cb, "Interface %s has bad superclass", cbName(cb));
93 result = FALSE;
94 }
95 for (i = cbMethodsCount(cb), mb = cbMethods(cb); --i >= 0; mb++) {
96 if (mb->fb.access & ACC_STATIC) {
97 if (mb->fb.name[0] != '<') {
98 /* Only internal methods can be static */
99 CCerror(cb, "Illegal static method %s in interface %s",
100 mb->fb.name, cbName(cb));
101 result = FALSE;
102 }
103 }
104 }
105 } else if (cbSuperclass(cb)) {
106 ClassClass *super_cb;
107 unsigned bitvector_size = (unsigned)(cbMethodTableSize(cb) + 31) >> 5;
108 long *bitvector = sysCalloc(bitvector_size, sizeof(long));
109 for (super_cb = cbSuperclass(cb); ; super_cb = cbSuperclass(super_cb)) {
110 if (cbAccess(super_cb) & ACC_FINAL) {
111 CCerror(cb, "Class %s is subclass of final class %s",
112 cbName(cb), cbName(super_cb));
113 result = FALSE;
114 }
115 mb = cbMethods(super_cb);
116 for (i = cbMethodsCount(super_cb); --i >= 0; mb++) {
117 if (mb->fb.access & ACC_FINAL) {
118 unsigned offset = mb->fb.u.offset;
119 bitvector[offset >> 5] |= (1 << (offset & 0x1F));
120 }
121 }
122 if (cbSuperclass(super_cb) == NULL) break;
123 }
124 for (i = cbMethodsCount(cb), mb = cbMethods(cb); --i >= 0; mb++) {
125 unsigned offset = mb->fb.u.offset;
126 if ((offset > 0)
127 && bitvector[offset >> 5] & (1 << (offset & 0x1F))) {
128 CCerror(cb, "Class %s overrides final method %s.%s",
129 cbName(cb), mb->fb.name, mb->fb.signature);
130 result = FALSE;
131 }
132 }
133 sysFree(bitvector);
134 } else if (cb != classJavaLangObject) {
135 CCerror(cb, "Class %s does not have superclass", cbName(cb));
136 result = FALSE;
137 }
138
139 if (result)
140 result = verify_class_codes(cb);
141 if (result)
142 CCSet(cb, Verified);
143 return result;
144}
145
146
147static bool_t
148verify_constant_pool(ClassClass *cb)
149{
150 union cp_item_type *cp = cbConstantPool(cb);
151 long cp_count = cbConstantPoolCount(cb);
152 unsigned char *type_table;
153 int i, type;
154
155 const int utf8_resolved = (CONSTANT_Utf8 | CONSTANT_POOL_ENTRY_RESOLVED);
156
157 if (cp_count == 0) /* Primitive classes */
158 return TRUE;
159 type_table = cp[CONSTANT_POOL_TYPE_TABLE_INDEX].type;
160 /* Let's make two quick passes over the constant pool. The first one
161 * checks that everything is of the right type. */
162 for (i = 1; i < cp_count; i++) {
163 switch(type = type_table[i]) {
164 case CONSTANT_String:
165 case CONSTANT_Class: {
166 int index = cp[i].i;
167 if ( (index < 1)
168 || (index >= cp_count)
169 || (type_table[index] != utf8_resolved)) {
170 CCerror(cb, "Bad index in constant pool #%d", i);
171 return FALSE;
172 }
173 break;
174 }
175
176 case CONSTANT_String | CONSTANT_POOL_ENTRY_RESOLVED:
177 /* This can only happen if a string is the "initial" value of
178 * some final static String. We assume that the checking has
179 * already been done.
180 */
181 break;
182
183 case CONSTANT_Fieldref:
184 case CONSTANT_Methodref:
185 case CONSTANT_InterfaceMethodref:
186 case CONSTANT_NameAndType: {
187 unsigned index = (unsigned)(cp[i].i);
188 int key1 = index >> 16;
189 int key2 = index & 0xFFFF;
190 if (key1 < 1 || key1 >= cp_count
191 || key2 < 1 || key2 >= cp_count) {
192 CCerror(cb, "Bad index in constant pool #%d", i);
193 return FALSE;
194 }
195 if (type == CONSTANT_NameAndType) {
196 if ( (type_table[key1] != utf8_resolved)
197 || (type_table[key2] != utf8_resolved)) {
198 CCerror(cb, "Bad index in constant pool.");
199 return FALSE;
200 }
201 } else {
202 if ( ((type_table[key1] & CONSTANT_POOL_ENTRY_TYPEMASK)
203 != CONSTANT_Class)
204 || ((type_table[key2] != CONSTANT_NameAndType))) {
205 CCerror(cb, "Bad index in constant pool #%d", i);
206 return FALSE;
207 }
208 }
209 break;
210 }
211
212 case CONSTANT_Fieldref | CONSTANT_POOL_ENTRY_RESOLVED:
213 case CONSTANT_Methodref | CONSTANT_POOL_ENTRY_RESOLVED:
214 case CONSTANT_InterfaceMethodref | CONSTANT_POOL_ENTRY_RESOLVED:
215 case CONSTANT_NameAndType | CONSTANT_POOL_ENTRY_RESOLVED:
216 CCerror(cb, "Improperly resolved constant pool #%d", i);
217 return FALSE;
218
219
220 case CONSTANT_Class | CONSTANT_POOL_ENTRY_RESOLVED:
221 case CONSTANT_Utf8 | CONSTANT_POOL_ENTRY_RESOLVED:
222 case CONSTANT_Integer | CONSTANT_POOL_ENTRY_RESOLVED:
223 case CONSTANT_Float | CONSTANT_POOL_ENTRY_RESOLVED:
224 break;
225
226 case CONSTANT_Long | CONSTANT_POOL_ENTRY_RESOLVED:
227 case CONSTANT_Double | CONSTANT_POOL_ENTRY_RESOLVED:
228 if ((i + 1 >= cp_count) ||
229 (type_table[i + 1] != CONSTANT_POOL_ENTRY_RESOLVED)) {
230 CCerror(cb, "Improper constant pool long/double #%d", i);
231 return FALSE;
232 } else {
233 i++;
234 break;
235 }
236
237 case CONSTANT_Integer:
238 case CONSTANT_Float:
239 case CONSTANT_Long:
240 case CONSTANT_Double:
241 case CONSTANT_Utf8:
242 CCerror(cb, "Improperly unresolved constant pool #%d", i);
243 return FALSE;
244
245
246 default:
247 CCerror(cb, "Illegal constant pool type at #%d", i);
248 return FALSE;
249
250
251 }
252 }
253 for (i = 1; i < cp_count; i++) {
254 switch(type = type_table[i]) {
255 case CONSTANT_Class: {
256 int index = cp[i].i;
257 if (!is_legal_fieldname(cb, cp[index].cp, LegalClass))
258 return FALSE;
259 break;
260 }
261
262 case CONSTANT_Fieldref:
263 case CONSTANT_Methodref:
264 case CONSTANT_InterfaceMethodref: {
265 unsigned index = (unsigned)(cp[i].i);
266 int name_type_index = index & 0xFFFF;
267 int name_type_key = cp[name_type_index].i;
268 int name_index = name_type_key >> 16;
269 int signature_index = name_type_key & 0xFFFF;
270 char *name = cp[name_index].cp;
271 char *signature = cp[signature_index].cp;
272
273 if (type == CONSTANT_Fieldref) {
274 if (! (is_legal_fieldname(cb, name, LegalField) &&
275 is_legal_field_signature(cb, name, signature)))
276 return FALSE;
277 } else {
278 if (! (is_legal_fieldname(cb, name, LegalMethod) &&
279 is_legal_method_signature(cb, name, signature)))
280 return FALSE;
281 }
282 break;
283 }
284 }
285 }
286 return TRUE;
287}
288
289
290/* Return true if the entire second argument consists of a legal fieldname
291 * (or classname, if the third argument is LegalClass).
292 */
293
294static bool_t
295is_legal_fieldname(ClassClass *cb, char *name, int type)
296{
297 bool_t result;
298 if (name[0] == '<') {
299 result = (type == LegalMethod) &&
300 ((strcmp(name, "<init>") == 0) ||
301 (strcmp(name, "<clinit>") == 0));
302 } else {
303 char *p;
304 if (type == LegalClass && name[0] == SIGNATURE_ARRAY) {
305 p = skip_over_field_signature(name, FALSE);
306 } else {
307 p = skip_over_fieldname(name, type == LegalClass);
308 }
309 result = (p != 0 && p[0] == '\0');
310 }
311 if (!result) {
312 char *thing = (type == LegalField) ? "Field"
313 : (type == LegalMethod) ? "Method" : "Class";
314
315 CCerror(cb, "Illegal %s name \"%s\"", thing, name);
316 return FALSE;
317 } else {
318 return TRUE;
319
320 }
321}
322
323/* Return true if the entire string consists of a legal field signature */
324static bool_t
325is_legal_field_signature(ClassClass *cb, char *fieldname, char *signature)
326{
327 char *p = skip_over_field_signature(signature, FALSE);
328 if (p != 0 && p[0] == '\0') {
329 return TRUE;
330 } else {
331 CCerror(cb, "Field \"%s\" has illegal signature \"%s\"",
332 fieldname, signature);
333 return FALSE;
334 }
335}
336
337
338static bool_t
339is_legal_method_signature(ClassClass *cb, char *methodname, char *signature)
340{
341 char *p = signature;
342 char *next_p;
343 /* The first character must be a '(' */
344 if (*p++ == SIGNATURE_FUNC) {
345 /* Skip over however many legal field signatures there are */
346 while ((next_p = skip_over_field_signature(p, FALSE)) != 0)
347 p = next_p;
348 /* The first non-signature thing better be a ')' */
349 if (*p++ == SIGNATURE_ENDFUNC) {
350 if (methodname[0] == '<') {
351 /* All internal methods must return void */
352 if ((p[0] == SIGNATURE_VOID) && (p[1] == '\0'))
353 return TRUE;
354 } else {
355 /* Now, we better just have a return value. */
356 next_p = skip_over_field_signature(p, TRUE);
357 if (next_p && next_p[0] == '\0')
358 return TRUE;
359 }
360 }
361 }
362 CCerror(cb, "Method \"%s\" has illegal signature \"%s\"",
363 methodname, signature);
364 return FALSE;
365}
366
367 $$Tables
368
369/*
370 * This code mirrors Character.isJavaIdentifierStart. It determines whether
371 * the specified character is a legal start of a Java identifier as per JLS.
372 *
373 * The parameter ch is the character to be tested; return 1 if the
374 * character is a letter, 0 otherwise.
375 */
376#define isJavaIdentifierStart(ch) ($$Lookup(ch) & $$maskIsJavaIdentifierStart)
377
378/*
379 * This code mirrors Character.isJavaIdentifierPart. It determines whether
380 * the specified character is a legal part of a Java identifier as per JLS.
381 *
382 * The parameter ch is the character to be tested; return 1 if the
383 * character is a digit, 0 otherwise.
384 */
385#define isJavaIdentifierPart(ch) ($$Lookup(ch) & $$maskIsJavaIdentifierPart)
386
387/* Take pointer to a string. Skip over the longest part of the string that
388 * could be taken as a fieldname. Allow '/' if slash_okay is TRUE.
389 *
390 * Return a pointer to just past the fieldname. Return NULL if no fieldname
391 * at all was found, or in the case of slash_okay being true, we saw
392 * consecutive slashes (meaning we were looking for a qualified path but
393 * found something that was badly-formed).
394 */
395static char *
396skip_over_fieldname(char *name, bool_t slash_okay)
397{
398 bool_t first;
399 char *p;
400 unicode last_ch = 0;
401 for (p = name, first = TRUE; ; first = FALSE) {
402 char *old_p = p;
403 unicode ch = next_utf2unicode(&p);
404 if (isJavaIdentifierStart(ch) || (!first && isJavaIdentifierPart(ch))
405 || (slash_okay && ch == '/' && !first)
406 || ch == '_' || ch == '$') {
407 if (ch == '/' && last_ch == '/') {
408 return 0; /* Don't permit consecutive slashes */
409 } else {
410 last_ch = ch;
411 }
412 } else {
413 return first ? 0 : old_p;
414 }
415 }
416}
417
418/* Take pointer to a string. Skip over the longest part of the string that
419 * could be taken as a field signature. Allow "void" if void_okay.
420 *
421 * Return a pointer to just past the signature. Return NULL if no legal
422 * signature is found.
423 */
424
425static char *
426skip_over_field_signature(char *name, bool_t void_okay)
427{
428 for (;;) {
429 switch (name[0]) {
430 case SIGNATURE_VOID:
431 if (!void_okay) return 0;
432 /* FALL THROUGH */
433 case SIGNATURE_BOOLEAN:
434 case SIGNATURE_BYTE:
435 case SIGNATURE_CHAR:
436 case SIGNATURE_SHORT:
437 case SIGNATURE_INT:
438 case SIGNATURE_FLOAT:
439 case SIGNATURE_LONG:
440 case SIGNATURE_DOUBLE:
441 return name + 1;
442
443 case SIGNATURE_CLASS: {
444 /* Skip over the classname, if one is there. */
445 char *p = skip_over_fieldname(name + 1, TRUE);
446 /* The next character better be a semicolon. */
447 if (p && p[0] == ';')
448 return p + 1;
449 return 0;
450 }
451
452 case SIGNATURE_ARRAY:
453 /* The rest of what's there better be a legal signature. */
454 name++;
455 void_okay = FALSE;
456 break;
457
458 default:
459 return 0;
460 }
461 }
462}
463
464
465static void
466CCerror (ClassClass *cb, char *format, ...)
467{
468 if (verbose) {
469 va_list args;
470 jio_fprintf(stderr, "VERIFIER CLASS ERROR %s:\n", cbName(cb));
471 va_start(args, format);
472 jio_vfprintf(stderr, format, args);
473 va_end(args);
474 jio_fprintf(stderr, "\n");
475 }
476}
477
478/* For use from outside the file. Determine if the specified name is legal
479 * UTF name for a classname.
480 *
481 * Note that this routine expects the internal form of qualified classes:
482 * the dots should have been replaced by slashes.
483 */
484bool_t IsLegalClassname(char *name, bool_t allowArrayClass)
485{
486 char *p;
487 if (name[0] == SIGNATURE_ARRAY) {
488 if (!allowArrayClass) {
489 return FALSE;
490 } else {
491 /* Everything that's left better be a field signature */
492 p = skip_over_field_signature(name, FALSE);
493 }
494 } else {
495 /* skip over the fieldname. Slashes are okay */
496 p = skip_over_fieldname(name, TRUE);
497 }
498 return (p != 0 && p[0] == '\0');
499}