You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by gs...@apache.org on 2007/02/13 21:55:01 UTC
svn commit: r507213 -
/harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Class_File_Loader.cpp
Author: gshimansky
Date: Tue Feb 13 12:55:00 2007
New Revision: 507213
URL: http://svn.apache.org/viewvc?view=rev&rev=507213
Log:
Applied HARMONY-3174 [drlvm][classloader] specjv98 tests failed due to wrong class file format checks.
Tests passed on Ubuntu6 x86, Windows XP x86 and SuSE9 x86_64
Modified:
harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Class_File_Loader.cpp
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Class_File_Loader.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Class_File_Loader.cpp?view=diff&rev=507213&r1=507212&r2=507213
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Class_File_Loader.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Class_File_Loader.cpp Tue Feb 13 12:55:00 2007
@@ -612,48 +612,61 @@
return true;
} //Class_Member::parse
-// JVM spec:
-// Unqualified names must not contain the characters â.â, â;â, â[â or â/â. Method names are
-// further constrained so that, with the exception of the special method names (§3.9)
-// <init> and <clinit>, they must not contain the characters â<â or â>â.
-static inline bool
-check_field_name(const char *name, unsigned len, bool old_version)
+static bool
+is_identifier(const char *name, unsigned len)
{
- TRACE2("field", "field: " << name << " " << len)
- if(old_version) {
- TRACE2("field", "symbol: " << *name);
- if(!(u_isalpha(*name) || *name == '$' || *name == '_'))
- return false;
- for (unsigned i = 1; i < len; i++) {
- TRACE2("field", "symbol: " << name[i]);
- if(!(u_isalnum(name[i]) || name[i] == '$' || name[i] == '_'))
- return false;
- }
- }else {
- for (unsigned i = 0; i < len; i++) {
- switch(name[i]){
- case '.':
- case ';':
- case '[':
- case '/':
- return false;
+ uint32 u_ch;
+ for(unsigned i = 0; i < len; i++) {
+ if(name[i] & 0x80) {
+ assert(name[i] & 0x40);
+ if(name[i] & 0x20) {
+ uint32 x = name[i];
+ i++;
+ uint32 y = name[i];
+ i++;
+ uint32 z = name[i];
+ u_ch = (uint32)(((0x0f & x) << 12) + ((0x3f & y) << 6) + ((0x3f & z)));
+ if(i == 2) {
+ if(!(u_isalpha(u_ch) || u_ch == '$' || u_ch == '_'))
+ return false;
+ } else {
+ if(!(u_isalnum(u_ch) || u_ch == '$' || u_ch == '_'))
+ return false;
+ }
+ } else {
+ uint32 x = name[i];
+ i++;
+ uint32 y = name[i];
+ u_ch = (uint32)(((0x1f & x) << 6) + (0x3f & y));
+ if(i == 1) {
+ if(!(u_isalpha(u_ch) || u_ch == '$' || u_ch == '_'))
+ return false;
+ }
+ if(!(u_isalnum(u_ch) || u_ch == '$' || u_ch == '_'))
+ return false;
+ }
+ } else {
+ u_ch = name[i];
+ if(i == 0) {
+ if(!(u_isalpha(u_ch) || u_ch == '$' || u_ch == '_'))
+ return false;
}
+ if(!(u_isalnum(u_ch) || u_ch == '$' || u_ch == '_'))
+ return false;
}
}
return true;
}
+// JVM spec:
+// Unqualified names must not contain the characters â.â, â;â, â[â or â/â. Method names are
+// further constrained so that, with the exception of the special method names (§3.9)
+// <init> and <clinit>, they must not contain the characters â<â or â>â.
static inline bool
-check_method_name(const char *name, unsigned len, bool old_version)
+check_member_name(const char *name, unsigned len, bool old_version, bool is_method)
{
if(old_version) {
- if(!(u_isalpha(*name) || *name == '$' || *name == '_'))
- return false;
- for (unsigned i = 1; i < len; i++) {
- TRACE2("field", "symbol: " << name[i]);
- if(!(u_isalnum(name[i]) || name[i] == '$' || name[i] == '_'))
- return false;
- }
+ return is_identifier(name, len);
}else {
for (unsigned i = 0; i < len; i++) {
switch(name[i]){
@@ -661,9 +674,11 @@
case ';':
case '[':
case '/':
+ return false;
case '<':
case '>':
- return false;
+ if(is_method)
+ return false;
}
}
}
@@ -709,7 +724,7 @@
return false;
}
if(*iterator == '/') {
- if(!check_field_name(descriptor, id_len, false))
+ if(!check_member_name(descriptor, id_len, false, false))
return false;
id_len = 0;
descriptor = iterator + 1;
@@ -717,7 +732,7 @@
id_len++;
}
}
- if(!check_field_name(descriptor, id_len, false))
+ if(!check_member_name(descriptor, id_len, false, false))
return false;
*next = iterator + 1;
return true;
@@ -763,8 +778,8 @@
if(!Class_Member::parse(clss, cfs))
return false;
if(env.verify_all
- && !check_field_name(_name->bytes, _name->len,
- clss->get_version() < JAVA5_CLASS_FILE_VERSION))
+ && !check_member_name(_name->bytes, _name->len,
+ clss->get_version() < JAVA5_CLASS_FILE_VERSION, false))
{
REPORT_FAILED_CLASS_FORMAT(clss, "illegal field name : " << _name->bytes);
return false;
@@ -1346,8 +1361,8 @@
if(!valid_cpi(_class, name_index, CONSTANT_Utf8, "for name of CONSTANT_Utf8 entry"))
return false;
String* name = cp.get_utf8_string(name_index);
- if(!check_field_name(name->bytes, name->len,
- _class->get_version() < JAVA5_CLASS_FILE_VERSION))
+ if(!check_member_name(name->bytes, name->len,
+ _class->get_version() < JAVA5_CLASS_FILE_VERSION, false))
{
REPORT_FAILED_METHOD("name of local variable: " << name->bytes <<
" in " << attr_name << " attribute is not stored as unqualified name");
@@ -1783,8 +1798,8 @@
//check name only if flag verify_all is set from command line
if(env.verify_all && !(_name == env.Init_String || _name == env.Clinit_String))
{
- if(!check_method_name(_name->bytes, _name->len,
- clss->get_version() < JAVA5_CLASS_FILE_VERSION))
+ if(!check_member_name(_name->bytes, _name->len,
+ clss->get_version() < JAVA5_CLASS_FILE_VERSION, true))
{
REPORT_FAILED_CLASS_FORMAT(clss, "illegal method name : " << _name->bytes);
return false;
@@ -2339,14 +2354,14 @@
if(*iterator != '/') {
id_len++;
} else {
- if(!check_field_name(name, id_len, false))
+ if(!check_member_name(name, id_len, false, false))
return false;
id_len = 0;
name = iterator;
name++;
}
}
- return check_field_name(name, id_len, false);
+ return check_member_name(name, id_len, false, false);
}
return false; //unreachable code
}
@@ -2603,7 +2618,7 @@
{
//check method name
if(env->verify_all && (name != env->Init_String)
- && !check_method_name(name->bytes,name->len, clss->get_version() < JAVA5_CLASS_FILE_VERSION))
+ && !check_member_name(name->bytes,name->len, clss->get_version() < JAVA5_CLASS_FILE_VERSION, true))
{
REPORT_FAILED_CLASS_CLASS(clss->get_class_loader(), clss, "java/lang/ClassFormatError",
clss->get_name()->bytes << ": illegal method name for CONSTANT_Methodref entry: " << name->bytes);
@@ -2633,11 +2648,11 @@
if(tag == CONSTANT_Fieldref)
{
//check field name
- if(env->verify_all && !check_field_name(name->bytes, name->len,
- clss->get_version() < JAVA5_CLASS_FILE_VERSION))
+ if(env->verify_all && !check_member_name(name->bytes, name->len,
+ clss->get_version() < JAVA5_CLASS_FILE_VERSION, false))
{
REPORT_FAILED_CLASS_CLASS(clss->get_class_loader(), clss, "java/lang/ClassFormatError",
- clss->get_name()->bytes << ": illegal filed name for CONSTANT_Filedref entry: " << name->bytes);
+ clss->get_name()->bytes << ": illegal field name for CONSTANT_Filedref entry: " << name->bytes);
return false;
}
//check field descriptor
@@ -2652,11 +2667,11 @@
{
//check method name, name can't be <init> or <clinit>
//See specification 4.5.2 about name_and_type_index last sentence.
- if(!check_method_name(name->bytes, name->len,
- clss->get_version() < JAVA5_CLASS_FILE_VERSION))
+ if(!check_member_name(name->bytes, name->len,
+ clss->get_version() < JAVA5_CLASS_FILE_VERSION, true))
{
REPORT_FAILED_CLASS_CLASS(clss->get_class_loader(), clss, "java/lang/ClassFormatError",
- clss->get_name()->bytes << ": illegal filed name for CONSTANT_InterfaceMethod entry: " << name->bytes);
+ clss->get_name()->bytes << ": illegal field name for CONSTANT_InterfaceMethod entry: " << name->bytes);
return false;
}
//check method descriptor