4989 // This method is also called from the modular system APIs in modules.cpp |
4989 // This method is also called from the modular system APIs in modules.cpp |
4990 // to verify the validity of module and package names. |
4990 // to verify the validity of module and package names. |
4991 bool ClassFileParser::verify_unqualified_name(const char* name, |
4991 bool ClassFileParser::verify_unqualified_name(const char* name, |
4992 unsigned int length, |
4992 unsigned int length, |
4993 int type) { |
4993 int type) { |
4994 for (const char* p = name; p != name + length;) { |
4994 for (const char* p = name; p != name + length; p++) { |
4995 jchar ch = *p; |
4995 switch(*p) { |
4996 if (ch < 128) { |
4996 case '.': |
4997 if (ch == '.' || ch == ';' || ch == '[' ) { |
4997 case ';': |
4998 return false; // do not permit '.', ';', or '[' |
4998 case '[': |
4999 } |
4999 // do not permit '.', ';', or '[' |
5000 if (ch == '/') { |
5000 return false; |
|
5001 case '/': |
5001 // check for '//' or leading or trailing '/' which are not legal |
5002 // check for '//' or leading or trailing '/' which are not legal |
5002 // unqualified name must not be empty |
5003 // unqualified name must not be empty |
5003 if (type == ClassFileParser::LegalClass) { |
5004 if (type == ClassFileParser::LegalClass) { |
5004 if (p == name || p+1 >= name+length || *(p+1) == '/') { |
5005 if (p == name || p+1 >= name+length || *(p+1) == '/') { |
5005 return false; |
5006 return false; |
5006 } |
5007 } |
5007 } else { |
5008 } else { |
5008 return false; // do not permit '/' unless it's class name |
5009 return false; // do not permit '/' unless it's class name |
5009 } |
5010 } |
5010 } |
5011 break; |
5011 if (type == ClassFileParser::LegalMethod && (ch == '<' || ch == '>')) { |
5012 case '<': |
5012 return false; // do not permit '<' or '>' in method names |
5013 case '>': |
5013 } |
5014 // do not permit '<' or '>' in method names |
5014 p++; |
5015 if (type == ClassFileParser::LegalMethod) { |
5015 } else { |
5016 return false; |
5016 char* tmp_p = UTF8::next(p, &ch); |
5017 } |
5017 p = tmp_p; |
|
5018 } |
5018 } |
5019 } |
5019 } |
5020 return true; |
5020 return true; |
5021 } |
5021 } |
5022 |
5022 |
5024 // be taken as a fieldname. Allow '/' if slash_ok is true. |
5024 // be taken as a fieldname. Allow '/' if slash_ok is true. |
5025 // Return a pointer to just past the fieldname. |
5025 // Return a pointer to just past the fieldname. |
5026 // Return NULL if no fieldname at all was found, or in the case of slash_ok |
5026 // Return NULL if no fieldname at all was found, or in the case of slash_ok |
5027 // being true, we saw consecutive slashes (meaning we were looking for a |
5027 // being true, we saw consecutive slashes (meaning we were looking for a |
5028 // qualified path but found something that was badly-formed). |
5028 // qualified path but found something that was badly-formed). |
5029 static const char* skip_over_field_name(const char* name, |
5029 static const char* skip_over_field_name(const char* const name, |
5030 bool slash_ok, |
5030 bool slash_ok, |
5031 unsigned int length) { |
5031 unsigned int length) { |
5032 const char* p; |
5032 const char* p; |
5033 jboolean last_is_slash = false; |
5033 jboolean last_is_slash = false; |
5034 jboolean not_first_ch = false; |
5034 jboolean not_first_ch = false; |
5060 p = tmp_p; |
5060 p = tmp_p; |
5061 last_is_slash = false; |
5061 last_is_slash = false; |
5062 // Check if ch is Java identifier start or is Java identifier part |
5062 // Check if ch is Java identifier start or is Java identifier part |
5063 // 4672820: call java.lang.Character methods directly without generating separate tables. |
5063 // 4672820: call java.lang.Character methods directly without generating separate tables. |
5064 EXCEPTION_MARK; |
5064 EXCEPTION_MARK; |
5065 |
|
5066 // return value |
5065 // return value |
5067 JavaValue result(T_BOOLEAN); |
5066 JavaValue result(T_BOOLEAN); |
5068 // Set up the arguments to isJavaIdentifierStart and isJavaIdentifierPart |
5067 // Set up the arguments to isJavaIdentifierStart or isJavaIdentifierPart |
5069 JavaCallArguments args; |
5068 JavaCallArguments args; |
5070 args.push_int(unicode_ch); |
5069 args.push_int(unicode_ch); |
5071 |
|
5072 // public static boolean isJavaIdentifierStart(char ch); |
|
5073 JavaCalls::call_static(&result, |
|
5074 SystemDictionary::Character_klass(), |
|
5075 vmSymbols::isJavaIdentifierStart_name(), |
|
5076 vmSymbols::int_bool_signature(), |
|
5077 &args, |
|
5078 THREAD); |
|
5079 |
|
5080 if (HAS_PENDING_EXCEPTION) { |
|
5081 CLEAR_PENDING_EXCEPTION; |
|
5082 return 0; |
|
5083 } |
|
5084 if (result.get_jboolean()) { |
|
5085 continue; |
|
5086 } |
|
5087 |
5070 |
5088 if (not_first_ch) { |
5071 if (not_first_ch) { |
5089 // public static boolean isJavaIdentifierPart(char ch); |
5072 // public static boolean isJavaIdentifierPart(char ch); |
5090 JavaCalls::call_static(&result, |
5073 JavaCalls::call_static(&result, |
5091 SystemDictionary::Character_klass(), |
5074 SystemDictionary::Character_klass(), |
5092 vmSymbols::isJavaIdentifierPart_name(), |
5075 vmSymbols::isJavaIdentifierPart_name(), |
5093 vmSymbols::int_bool_signature(), |
5076 vmSymbols::int_bool_signature(), |
5094 &args, |
5077 &args, |
5095 THREAD); |
5078 THREAD); |
5096 |
5079 } else { |
5097 if (HAS_PENDING_EXCEPTION) { |
5080 // public static boolean isJavaIdentifierStart(char ch); |
5098 CLEAR_PENDING_EXCEPTION; |
5081 JavaCalls::call_static(&result, |
5099 return 0; |
5082 SystemDictionary::Character_klass(), |
5100 } |
5083 vmSymbols::isJavaIdentifierStart_name(), |
5101 |
5084 vmSymbols::int_bool_signature(), |
5102 if (result.get_jboolean()) { |
5085 &args, |
5103 continue; |
5086 THREAD); |
5104 } |
5087 } |
|
5088 if (HAS_PENDING_EXCEPTION) { |
|
5089 CLEAR_PENDING_EXCEPTION; |
|
5090 return NULL; |
|
5091 } |
|
5092 if(result.get_jboolean()) { |
|
5093 continue; |
5105 } |
5094 } |
5106 } |
5095 } |
5107 return (not_first_ch) ? old_p : NULL; |
5096 return (not_first_ch) ? old_p : NULL; |
5108 } |
5097 } |
5109 return (not_first_ch) ? p : NULL; |
5098 return (not_first_ch) ? p : NULL; |
5140 return p + 1; |
5129 return p + 1; |
5141 } |
5130 } |
5142 } |
5131 } |
5143 else { |
5132 else { |
5144 // Skip leading 'L' and ignore first appearance of ';' |
5133 // Skip leading 'L' and ignore first appearance of ';' |
5145 length--; |
|
5146 signature++; |
5134 signature++; |
5147 char* c = strchr((char*) signature, ';'); |
5135 char* c = strchr((char*) signature, ';'); |
5148 // Format check signature |
5136 // Format check signature |
5149 if (c != NULL) { |
5137 if (c != NULL) { |
5150 ResourceMark rm(THREAD); |
|
5151 int newlen = c - (char*) signature; |
5138 int newlen = c - (char*) signature; |
5152 char* sig = NEW_RESOURCE_ARRAY(char, newlen + 1); |
5139 bool legal = verify_unqualified_name(signature, newlen, LegalClass); |
5153 strncpy(sig, signature, newlen); |
|
5154 sig[newlen] = '\0'; |
|
5155 |
|
5156 bool legal = verify_unqualified_name(sig, newlen, LegalClass); |
|
5157 if (!legal) { |
5140 if (!legal) { |
5158 classfile_parse_error("Class name contains illegal character " |
5141 classfile_parse_error("Class name contains illegal character " |
5159 "in descriptor in class file %s", |
5142 "in descriptor in class file %s", |
5160 CHECK_0); |
5143 CHECK_0); |
5161 return NULL; |
5144 return NULL; |
5185 |
5168 |
5186 // Checks if name is a legal class name. |
5169 // Checks if name is a legal class name. |
5187 void ClassFileParser::verify_legal_class_name(const Symbol* name, TRAPS) const { |
5170 void ClassFileParser::verify_legal_class_name(const Symbol* name, TRAPS) const { |
5188 if (!_need_verify || _relax_verify) { return; } |
5171 if (!_need_verify || _relax_verify) { return; } |
5189 |
5172 |
5190 char buf[fixed_buffer_size]; |
5173 assert(name->refcount() > 0, "symbol must be kept alive"); |
5191 char* bytes = name->as_utf8_flexible_buffer(THREAD, buf, fixed_buffer_size); |
5174 char* bytes = (char*)name->bytes(); |
5192 unsigned int length = name->utf8_length(); |
5175 unsigned int length = name->utf8_length(); |
5193 bool legal = false; |
5176 bool legal = false; |
5194 |
5177 |
5195 if (length > 0) { |
5178 if (length > 0) { |
5196 const char* p; |
5179 const char* p; |
5225 |
5208 |
5226 // Checks if name is a legal field name. |
5209 // Checks if name is a legal field name. |
5227 void ClassFileParser::verify_legal_field_name(const Symbol* name, TRAPS) const { |
5210 void ClassFileParser::verify_legal_field_name(const Symbol* name, TRAPS) const { |
5228 if (!_need_verify || _relax_verify) { return; } |
5211 if (!_need_verify || _relax_verify) { return; } |
5229 |
5212 |
5230 char buf[fixed_buffer_size]; |
5213 char* bytes = (char*)name->bytes(); |
5231 char* bytes = name->as_utf8_flexible_buffer(THREAD, buf, fixed_buffer_size); |
|
5232 unsigned int length = name->utf8_length(); |
5214 unsigned int length = name->utf8_length(); |
5233 bool legal = false; |
5215 bool legal = false; |
5234 |
5216 |
5235 if (length > 0) { |
5217 if (length > 0) { |
5236 if (_major_version < JAVA_1_5_VERSION) { |
5218 if (_major_version < JAVA_1_5_VERSION) { |
5260 // Checks if name is a legal method name. |
5242 // Checks if name is a legal method name. |
5261 void ClassFileParser::verify_legal_method_name(const Symbol* name, TRAPS) const { |
5243 void ClassFileParser::verify_legal_method_name(const Symbol* name, TRAPS) const { |
5262 if (!_need_verify || _relax_verify) { return; } |
5244 if (!_need_verify || _relax_verify) { return; } |
5263 |
5245 |
5264 assert(name != NULL, "method name is null"); |
5246 assert(name != NULL, "method name is null"); |
5265 char buf[fixed_buffer_size]; |
5247 char* bytes = (char*)name->bytes(); |
5266 char* bytes = name->as_utf8_flexible_buffer(THREAD, buf, fixed_buffer_size); |
|
5267 unsigned int length = name->utf8_length(); |
5248 unsigned int length = name->utf8_length(); |
5268 bool legal = false; |
5249 bool legal = false; |
5269 |
5250 |
5270 if (length > 0) { |
5251 if (length > 0) { |
5271 if (bytes[0] == '<') { |
5252 if (bytes[0] == '<') { |
5300 void ClassFileParser::verify_legal_field_signature(const Symbol* name, |
5281 void ClassFileParser::verify_legal_field_signature(const Symbol* name, |
5301 const Symbol* signature, |
5282 const Symbol* signature, |
5302 TRAPS) const { |
5283 TRAPS) const { |
5303 if (!_need_verify) { return; } |
5284 if (!_need_verify) { return; } |
5304 |
5285 |
5305 char buf[fixed_buffer_size]; |
5286 const char* const bytes = (const char* const)signature->bytes(); |
5306 const char* const bytes = signature->as_utf8_flexible_buffer(THREAD, buf, fixed_buffer_size); |
|
5307 const unsigned int length = signature->utf8_length(); |
5287 const unsigned int length = signature->utf8_length(); |
5308 const char* const p = skip_over_field_signature(bytes, false, length, CHECK); |
5288 const char* const p = skip_over_field_signature(bytes, false, length, CHECK); |
5309 |
5289 |
5310 if (p == NULL || (p - bytes) != (int)length) { |
5290 if (p == NULL || (p - bytes) != (int)length) { |
5311 throwIllegalSignature("Field", name, signature, CHECK); |
5291 throwIllegalSignature("Field", name, signature, CHECK); |
5330 throwIllegalSignature("Method", name, signature, CHECK_0); |
5310 throwIllegalSignature("Method", name, signature, CHECK_0); |
5331 return 0; |
5311 return 0; |
5332 } |
5312 } |
5333 |
5313 |
5334 unsigned int args_size = 0; |
5314 unsigned int args_size = 0; |
5335 char buf[fixed_buffer_size]; |
5315 const char* p = (const char*)signature->bytes(); |
5336 const char* p = signature->as_utf8_flexible_buffer(THREAD, buf, fixed_buffer_size); |
|
5337 unsigned int length = signature->utf8_length(); |
5316 unsigned int length = signature->utf8_length(); |
5338 const char* nextp; |
5317 const char* nextp; |
5339 |
5318 |
5340 // The first character must be a '(' |
5319 // The first character must be a '(' |
5341 if ((length > 0) && (*p++ == JVM_SIGNATURE_FUNC)) { |
5320 if ((length > 0) && (*p++ == JVM_SIGNATURE_FUNC)) { |