diff options
author | Per Bothner <per@bothner.com> | 2001-02-23 20:15:31 -0800 |
---|---|---|
committer | Per Bothner <bothner@gcc.gnu.org> | 2001-02-23 20:15:31 -0800 |
commit | f9edddabe7c6ec77d525d7e4008b946ce4a1e2f8 (patch) | |
tree | 8f057d79ffefb9eb0ef8f70de17c0a8db0af7b3c | |
parent | 5ea1bc0e465cdbe8e2b49b8d1aff902b32b89abe (diff) | |
download | gcc-f9edddabe7c6ec77d525d7e4008b946ce4a1e2f8.zip gcc-f9edddabe7c6ec77d525d7e4008b946ce4a1e2f8.tar.gz gcc-f9edddabe7c6ec77d525d7e4008b946ce4a1e2f8.tar.bz2 |
Change to sometimes include class name in ClassFormatError message.
From-SVN: r40030
-rw-r--r-- | libjava/ChangeLog | 14 | ||||
-rw-r--r-- | libjava/defineclass.cc | 142 | ||||
-rw-r--r-- | libjava/include/java-interp.h | 10 | ||||
-rw-r--r-- | libjava/java/lang/natClassLoader.cc | 4 |
4 files changed, 115 insertions, 55 deletions
diff --git a/libjava/ChangeLog b/libjava/ChangeLog index 7a467f5..0bf0ea9 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,5 +1,19 @@ 2001-02-23 Per Bothner <per@bothner.com> + Change to sometimes include class name in ClassFormatError message. + * defineclass.cc (_Jv_VerifyFieldSignature, _Jv_VerifyMethodSignature, + _Jv_VerifyIdentifier, _Jv_VerifyClassName (two overlods)): Return + boolean instead of throwing ClassFormatError on failure. + (throw_class_format_error): Change static function to method. + (_Jv_ClassReader): New inline methods verify_identifier, + two overloads of verify_classname, verify_field_signature, and + verify_method_signature + * include/java-interp.h: Update declarations to return bool. + * java/lang/natClassLoader.cc (defineClass0): Explicitly throw + ClassFormatError since _Jv_VerifyClassName now returns bool. + +2001-02-23 Per Bothner <per@bothner.com> + * java/lang/Throwable.java (CPlusPlusDemangler): Pass -s java to c++filt to select java-style output. diff --git a/libjava/defineclass.cc b/libjava/defineclass.cc index d580516..962b835 100644 --- a/libjava/defineclass.cc +++ b/libjava/defineclass.cc @@ -56,8 +56,6 @@ static void throw_no_class_def_found_error (char *msg) __attribute__ ((__noreturn__)); static void throw_class_format_error (jstring msg) __attribute__ ((__noreturn__)); -static void throw_class_format_error (char *msg) - __attribute__ ((__noreturn__)); static void throw_incompatible_class_change_error (jstring msg) __attribute__ ((__noreturn__)); static void throw_class_circularity_error (jstring msg) @@ -191,6 +189,36 @@ struct _Jv_ClassReader { throw_class_format_error ("erroneous constant pool tag"); } + inline void verify_identifier (_Jv_Utf8Const* name) + { + if (! _Jv_VerifyIdentifier (name)) + throw_class_format_error ("erroneous identifier"); + } + + inline void verify_classname (unsigned char* ptr, _Jv_ushort length) + { + if (! _Jv_VerifyClassName (ptr, length)) + throw_class_format_error ("erroneous class name"); + } + + inline void verify_classname (_Jv_Utf8Const *name) + { + if (! _Jv_VerifyClassName (name)) + throw_class_format_error ("erroneous class name"); + } + + inline void verify_field_signature (_Jv_Utf8Const *sig) + { + if (! _Jv_VerifyFieldSignature (sig)) + throw_class_format_error ("erroneous type descriptor"); + } + + inline void verify_method_signature (_Jv_Utf8Const *sig) + { + if (! _Jv_VerifyMethodSignature (sig)) + throw_class_format_error ("erroneous type descriptor"); + } + _Jv_ClassReader (jclass klass, jbyteArray data, jint offset, jint length) { if (klass == 0 || length < 0 || offset+length > data->length) @@ -213,6 +241,7 @@ struct _Jv_ClassReader { void read_one_method_attribute (int method); void read_one_code_attribute (int method); void read_one_field_attribute (int field); + void throw_class_format_error (char *msg); /** check an utf8 entry, without creating a Utf8Const object */ bool is_attribute_name (int index, char *name); @@ -699,7 +728,7 @@ _Jv_ClassReader::prepare_pool_entry (int index, unsigned char this_tag) prepare_pool_entry (utf_index, JV_CONSTANT_Utf8); if (verify) - _Jv_VerifyClassName (pool_data[utf_index].utf8); + verify_classname (pool_data[utf_index].utf8); pool_data[index].utf8 = pool_data[utf_index].utf8; pool_tags[index] = JV_CONSTANT_Class; @@ -742,7 +771,7 @@ _Jv_ClassReader::prepare_pool_entry (int index, unsigned char this_tag) || _Jv_equalUtf8Consts (name, init_name))) /* ignore */; else - _Jv_VerifyIdentifier (pool_data[name_index].utf8); + verify_identifier (pool_data[name_index].utf8); } _Jv_storeIndexes (&pool_data[index], class_index, nat_index); @@ -1030,7 +1059,7 @@ void _Jv_ClassReader::handleField (int field_no, #endif if (verify) - _Jv_VerifyIdentifier (field_name); + verify_identifier (field_name); // ignore flags we don't know about. field->flags = flags & Modifier::ALL_FLAGS; @@ -1184,7 +1213,7 @@ void _Jv_ClassReader::handleMethod || _Jv_equalUtf8Consts (method->name, init_name)) /* ignore */; else - _Jv_VerifyIdentifier (method->name); + verify_identifier (method->name); _Jv_VerifyMethodSignature (method->signature); @@ -1274,6 +1303,36 @@ void _Jv_ClassReader::handleMethodsEnd () } +void _Jv_ClassReader::throw_class_format_error (char *msg) +{ + jstring str; + if (def->name != NULL) + { + jsize mlen = strlen (msg); + unsigned char* data = (unsigned char*) def->name->data; + int ulen = def->name->length; + unsigned char* limit = data + ulen; + jsize nlen = _Jv_strLengthUtf8 ((char *) data, ulen); + jsize len = nlen + mlen + 3; + str = JvAllocString(len); + jchar *chrs = JvGetStringChars(str); + while (data < limit) + *chrs++ = UTF8_GET(data, limit); + *chrs++ = ' '; + *chrs++ = '('; + for (;;) + { + char c = *msg++; + if (c == 0) + break; + *chrs++ = c & 0xFFFF; + } + *chrs++ = ')'; + } + else + str = JvNewStringLatin1 (msg); + ::throw_class_format_error (str); +} /** This section takes care of verifying integrity of identifiers, signatures, field ddescriptors, and class names */ @@ -1314,7 +1373,8 @@ _Jv_VerifyOne (unsigned char* ptr, unsigned char* limit, bool void_ok) return 0; } while (ch != ';'); - _Jv_VerifyClassName (start, (unsigned short) (end-start)); + if (! _Jv_VerifyClassName (start, (unsigned short) (end-start))) + return 0; } break; @@ -1333,7 +1393,7 @@ _Jv_VerifyOne (unsigned char* ptr, unsigned char* limit, bool void_ok) /** verification and loading procedures **/ -void +bool _Jv_VerifyFieldSignature (_Jv_Utf8Const*sig) { unsigned char* ptr = (unsigned char*) sig->data; @@ -1341,36 +1401,28 @@ _Jv_VerifyFieldSignature (_Jv_Utf8Const*sig) ptr = _Jv_VerifyOne (ptr, limit, false); - if (ptr != limit) - throw_class_format_error ("erroneous type descriptor"); + return ptr == limit; } -void +bool _Jv_VerifyMethodSignature (_Jv_Utf8Const*sig) { unsigned char* ptr = (unsigned char*) sig->data; unsigned char* limit = ptr + sig->length; - if (ptr == limit) - throw_class_format_error ("erroneous type descriptor"); - - if (UTF8_GET(ptr,limit) != '(') - throw_class_format_error ("erroneous type descriptor"); + if (ptr == limit || UTF8_GET(ptr,limit) != '(') + return false; while (ptr && UTF8_PEEK (ptr, limit) != ')') ptr = _Jv_VerifyOne (ptr, limit, false); if (UTF8_GET (ptr, limit) != ')') - throw_class_format_error ("erroneous type descriptor"); + return false; // get the return type ptr = _Jv_VerifyOne (ptr, limit, true); - if (ptr != limit) - throw_class_format_error ("erroneous type descriptor"); - - return; - + return ptr == limit; } /* we try to avoid calling the Character methods all the time, @@ -1408,7 +1460,7 @@ is_identifier_part (int c) return character->isJavaIdentifierStart ((jchar) ch); } -void +bool _Jv_VerifyIdentifier (_Jv_Utf8Const* name) { unsigned char *ptr = (unsigned char*) name->data; @@ -1417,18 +1469,18 @@ _Jv_VerifyIdentifier (_Jv_Utf8Const* name) if ((ch = UTF8_GET (ptr, limit))==-1 || ! is_identifier_start (ch)) - throw_class_format_error ("erroneous identifier"); + return false; while (ptr != limit) { if ((ch = UTF8_GET (ptr, limit))==-1 || ! is_identifier_part (ch)) - throw_class_format_error ("erroneous identifier"); + return false; } + return true; } - -void +bool _Jv_VerifyClassName (unsigned char* ptr, _Jv_ushort length) { unsigned char *limit = ptr+length; @@ -1437,39 +1489,37 @@ _Jv_VerifyClassName (unsigned char* ptr, _Jv_ushort length) if ('[' == UTF8_PEEK (ptr, limit)) { if (! _Jv_VerifyOne (++ptr, limit, false)) - throw_class_format_error ("erroneous class name"); + return false; else - return; + return true; } next_level: - do { + for (;;) { if ((ch = UTF8_GET (ptr, limit))==-1) - throw_class_format_error ("erroneous class name"); + return false; if (! is_identifier_start (ch)) - throw_class_format_error ("erroneous class name"); - do { + return false; + for (;;) { if (ptr == limit) - return; + return true; else if ((ch = UTF8_GET (ptr, limit))==-1) - throw_class_format_error ("erroneous class name"); + return false; else if (ch == '.') goto next_level; else if (! is_identifier_part (ch)) - throw_class_format_error ("erroneous class name"); - } while (true); - } while (true); - + return false; + } + } } -void +bool _Jv_VerifyClassName (_Jv_Utf8Const *name) { - _Jv_VerifyClassName ((unsigned char*)&name->data[0], - (_Jv_ushort) name->length); + return _Jv_VerifyClassName ((unsigned char*)&name->data[0], + (_Jv_ushort) name->length); } - /** returns true, if name1 and name2 represents classes in the same package. */ @@ -1548,12 +1598,6 @@ throw_class_format_error (jstring msg) } static void -throw_class_format_error (char *msg) -{ - throw_class_format_error (JvNewStringLatin1 (msg)); -} - -static void throw_internal_error (char *msg) { JvThrow diff --git a/libjava/include/java-interp.h b/libjava/include/java-interp.h index 59976b3..acc2eb9 100644 --- a/libjava/include/java-interp.h +++ b/libjava/include/java-interp.h @@ -33,11 +33,11 @@ _Jv_IsInterpretedClass (jclass c) struct _Jv_ResolvedMethod; -void _Jv_VerifyFieldSignature (_Jv_Utf8Const*sig); -void _Jv_VerifyMethodSignature (_Jv_Utf8Const*sig); -void _Jv_VerifyClassName (unsigned char* ptr, _Jv_ushort length); -void _Jv_VerifyClassName (_Jv_Utf8Const *name); -void _Jv_VerifyIdentifier (_Jv_Utf8Const *); +bool _Jv_VerifyFieldSignature (_Jv_Utf8Const*sig); +bool _Jv_VerifyMethodSignature (_Jv_Utf8Const*sig); +bool _Jv_VerifyClassName (unsigned char* ptr, _Jv_ushort length); +bool _Jv_VerifyClassName (_Jv_Utf8Const *name); +bool _Jv_VerifyIdentifier (_Jv_Utf8Const *); bool _Jv_ClassNameSamePackage (_Jv_Utf8Const *name1, _Jv_Utf8Const *name2); void _Jv_DefineClass (jclass, jbyteArray, jint, jint); void _Jv_ResolveField (_Jv_Field *, java::lang::ClassLoader*); diff --git a/libjava/java/lang/natClassLoader.cc b/libjava/java/lang/natClassLoader.cc index 979de3f..5f7138c 100644 --- a/libjava/java/lang/natClassLoader.cc +++ b/libjava/java/lang/natClassLoader.cc @@ -79,7 +79,9 @@ java::lang::ClassLoader::defineClass0 (jstring name, { _Jv_Utf8Const * name2 = _Jv_makeUtf8Const (name); - _Jv_VerifyClassName (name2); + if (! _Jv_VerifyClassName (name2)) + JvThrow (new java::lang::ClassFormatError + (JvNewStringLatin1 ("erroneous class name"))); klass->name = name2; } |