src/hotspot/share/classfile/classFileParser.cpp
changeset 58722 cba8afa5cfed
parent 58447 319173c62caa
child 58817 7f27d70a2424
equal deleted inserted replaced
58720:ae0af9fb3dbb 58722:cba8afa5cfed
   729           }
   729           }
   730           // 4509014: If a class method name begins with '<', it must be "<init>"
   730           // 4509014: If a class method name begins with '<', it must be "<init>"
   731           const unsigned int name_len = name->utf8_length();
   731           const unsigned int name_len = name->utf8_length();
   732           if (tag == JVM_CONSTANT_Methodref &&
   732           if (tag == JVM_CONSTANT_Methodref &&
   733               name_len != 0 &&
   733               name_len != 0 &&
   734               name->char_at(0) == '<' &&
   734               name->char_at(0) == JVM_SIGNATURE_SPECIAL &&
   735               name != vmSymbols::object_initializer_name()) {
   735               name != vmSymbols::object_initializer_name()) {
   736             classfile_parse_error(
   736             classfile_parse_error(
   737               "Bad method name at constant pool index %u in class file %s",
   737               "Bad method name at constant pool index %u in class file %s",
   738               name_ref_index, CHECK);
   738               name_ref_index, CHECK);
   739           }
   739           }
  4959                                               unsigned int length,
  4959                                               unsigned int length,
  4960                                               int type) {
  4960                                               int type) {
  4961   if (length == 0) return false;  // Must have at least one char.
  4961   if (length == 0) return false;  // Must have at least one char.
  4962   for (const char* p = name; p != name + length; p++) {
  4962   for (const char* p = name; p != name + length; p++) {
  4963     switch(*p) {
  4963     switch(*p) {
  4964       case '.':
  4964       case JVM_SIGNATURE_DOT:
  4965       case ';':
  4965       case JVM_SIGNATURE_ENDCLASS:
  4966       case '[':
  4966       case JVM_SIGNATURE_ARRAY:
  4967         // do not permit '.', ';', or '['
  4967         // do not permit '.', ';', or '['
  4968         return false;
  4968         return false;
  4969       case '/':
  4969       case JVM_SIGNATURE_SLASH:
  4970         // check for '//' or leading or trailing '/' which are not legal
  4970         // check for '//' or leading or trailing '/' which are not legal
  4971         // unqualified name must not be empty
  4971         // unqualified name must not be empty
  4972         if (type == ClassFileParser::LegalClass) {
  4972         if (type == ClassFileParser::LegalClass) {
  4973           if (p == name || p+1 >= name+length || *(p+1) == '/') {
  4973           if (p == name || p+1 >= name+length ||
       
  4974               *(p+1) == JVM_SIGNATURE_SLASH) {
  4974             return false;
  4975             return false;
  4975           }
  4976           }
  4976         } else {
  4977         } else {
  4977           return false;   // do not permit '/' unless it's class name
  4978           return false;   // do not permit '/' unless it's class name
  4978         }
  4979         }
  4979         break;
  4980         break;
  4980       case '<':
  4981       case JVM_SIGNATURE_SPECIAL:
  4981       case '>':
  4982       case JVM_SIGNATURE_ENDSPECIAL:
  4982         // do not permit '<' or '>' in method names
  4983         // do not permit '<' or '>' in method names
  4983         if (type == ClassFileParser::LegalMethod) {
  4984         if (type == ClassFileParser::LegalMethod) {
  4984           return false;
  4985           return false;
  4985         }
  4986         }
  4986     }
  4987     }
  5013         (ch == '_' || ch == '$') ||
  5014         (ch == '_' || ch == '$') ||
  5014         (not_first_ch && ch >= '0' && ch <= '9')) {
  5015         (not_first_ch && ch >= '0' && ch <= '9')) {
  5015         last_is_slash = false;
  5016         last_is_slash = false;
  5016         continue;
  5017         continue;
  5017       }
  5018       }
  5018       if (slash_ok && ch == '/') {
  5019       if (slash_ok && ch == JVM_SIGNATURE_SLASH) {
  5019         if (last_is_slash) {
  5020         if (last_is_slash) {
  5020           return NULL;  // Don't permit consecutive slashes
  5021           return NULL;  // Don't permit consecutive slashes
  5021         }
  5022         }
  5022         last_is_slash = true;
  5023         last_is_slash = true;
  5023         continue;
  5024         continue;
  5093       if (_major_version < JAVA_1_5_VERSION) {
  5094       if (_major_version < JAVA_1_5_VERSION) {
  5094         // Skip over the class name if one is there
  5095         // Skip over the class name if one is there
  5095         const char* const p = skip_over_field_name(signature + 1, true, --length);
  5096         const char* const p = skip_over_field_name(signature + 1, true, --length);
  5096 
  5097 
  5097         // The next character better be a semicolon
  5098         // The next character better be a semicolon
  5098         if (p && (p - signature) > 1 && p[0] == ';') {
  5099         if (p && (p - signature) > 1 && p[0] == JVM_SIGNATURE_ENDCLASS) {
  5099           return p + 1;
  5100           return p + 1;
  5100         }
  5101         }
  5101       }
  5102       }
  5102       else {
  5103       else {
  5103         // Skip leading 'L' and ignore first appearance of ';'
  5104         // Skip leading 'L' and ignore first appearance of ';'
  5104         signature++;
  5105         signature++;
  5105         const char* c = (const char*) memchr(signature, ';', length - 1);
  5106         const char* c = (const char*) memchr(signature, JVM_SIGNATURE_ENDCLASS, length - 1);
  5106         // Format check signature
  5107         // Format check signature
  5107         if (c != NULL) {
  5108         if (c != NULL) {
  5108           int newlen = c - (char*) signature;
  5109           int newlen = c - (char*) signature;
  5109           bool legal = verify_unqualified_name(signature, newlen, LegalClass);
  5110           bool legal = verify_unqualified_name(signature, newlen, LegalClass);
  5110           if (!legal) {
  5111           if (!legal) {
  5149     const char* p;
  5150     const char* p;
  5150     if (bytes[0] == JVM_SIGNATURE_ARRAY) {
  5151     if (bytes[0] == JVM_SIGNATURE_ARRAY) {
  5151       p = skip_over_field_signature(bytes, false, length, CHECK);
  5152       p = skip_over_field_signature(bytes, false, length, CHECK);
  5152       legal = (p != NULL) && ((p - bytes) == (int)length);
  5153       legal = (p != NULL) && ((p - bytes) == (int)length);
  5153     } else if (_major_version < JAVA_1_5_VERSION) {
  5154     } else if (_major_version < JAVA_1_5_VERSION) {
  5154       if (bytes[0] != '<') {
  5155       if (bytes[0] != JVM_SIGNATURE_SPECIAL) {
  5155         p = skip_over_field_name(bytes, true, length);
  5156         p = skip_over_field_name(bytes, true, length);
  5156         legal = (p != NULL) && ((p - bytes) == (int)length);
  5157         legal = (p != NULL) && ((p - bytes) == (int)length);
  5157       }
  5158       }
  5158     } else {
  5159     } else {
  5159       // 4900761: relax the constraints based on JSR202 spec
  5160       // 4900761: relax the constraints based on JSR202 spec
  5184   unsigned int length = name->utf8_length();
  5185   unsigned int length = name->utf8_length();
  5185   bool legal = false;
  5186   bool legal = false;
  5186 
  5187 
  5187   if (length > 0) {
  5188   if (length > 0) {
  5188     if (_major_version < JAVA_1_5_VERSION) {
  5189     if (_major_version < JAVA_1_5_VERSION) {
  5189       if (bytes[0] != '<') {
  5190       if (bytes[0] != JVM_SIGNATURE_SPECIAL) {
  5190         const char* p = skip_over_field_name(bytes, false, length);
  5191         const char* p = skip_over_field_name(bytes, false, length);
  5191         legal = (p != NULL) && ((p - bytes) == (int)length);
  5192         legal = (p != NULL) && ((p - bytes) == (int)length);
  5192       }
  5193       }
  5193     } else {
  5194     } else {
  5194       // 4881221: relax the constraints based on JSR202 spec
  5195       // 4881221: relax the constraints based on JSR202 spec
  5217   char* bytes = (char*)name->bytes();
  5218   char* bytes = (char*)name->bytes();
  5218   unsigned int length = name->utf8_length();
  5219   unsigned int length = name->utf8_length();
  5219   bool legal = false;
  5220   bool legal = false;
  5220 
  5221 
  5221   if (length > 0) {
  5222   if (length > 0) {
  5222     if (bytes[0] == '<') {
  5223     if (bytes[0] == JVM_SIGNATURE_SPECIAL) {
  5223       if (name == vmSymbols::object_initializer_name() || name == vmSymbols::class_initializer_name()) {
  5224       if (name == vmSymbols::object_initializer_name() || name == vmSymbols::class_initializer_name()) {
  5224         legal = true;
  5225         legal = true;
  5225       }
  5226       }
  5226     } else if (_major_version < JAVA_1_5_VERSION) {
  5227     } else if (_major_version < JAVA_1_5_VERSION) {
  5227       const char* p;
  5228       const char* p;
  5301       nextp = skip_over_field_signature(p, false, length, CHECK_0);
  5302       nextp = skip_over_field_signature(p, false, length, CHECK_0);
  5302     }
  5303     }
  5303     // The first non-signature thing better be a ')'
  5304     // The first non-signature thing better be a ')'
  5304     if ((length > 0) && (*p++ == JVM_SIGNATURE_ENDFUNC)) {
  5305     if ((length > 0) && (*p++ == JVM_SIGNATURE_ENDFUNC)) {
  5305       length--;
  5306       length--;
  5306       if (name->utf8_length() > 0 && name->char_at(0) == '<') {
  5307       if (name->utf8_length() > 0 && name->char_at(0) == JVM_SIGNATURE_SPECIAL) {
  5307         // All internal methods must return void
  5308         // All internal methods must return void
  5308         if ((length == 1) && (p[0] == JVM_SIGNATURE_VOID)) {
  5309         if ((length == 1) && (p[0] == JVM_SIGNATURE_VOID)) {
  5309           return args_size;
  5310           return args_size;
  5310         }
  5311         }
  5311       } else {
  5312       } else {
  5703 // For an unsafe anonymous class that is in the unnamed package, move it to its host class's
  5704 // For an unsafe anonymous class that is in the unnamed package, move it to its host class's
  5704 // package by prepending its host class's package name to its class name and setting
  5705 // package by prepending its host class's package name to its class name and setting
  5705 // its _class_name field.
  5706 // its _class_name field.
  5706 void ClassFileParser::prepend_host_package_name(const InstanceKlass* unsafe_anonymous_host, TRAPS) {
  5707 void ClassFileParser::prepend_host_package_name(const InstanceKlass* unsafe_anonymous_host, TRAPS) {
  5707   ResourceMark rm(THREAD);
  5708   ResourceMark rm(THREAD);
  5708   assert(strrchr(_class_name->as_C_string(), '/') == NULL,
  5709   assert(strrchr(_class_name->as_C_string(), JVM_SIGNATURE_SLASH) == NULL,
  5709          "Unsafe anonymous class should not be in a package");
  5710          "Unsafe anonymous class should not be in a package");
  5710   const char* host_pkg_name =
  5711   const char* host_pkg_name =
  5711     ClassLoader::package_from_name(unsafe_anonymous_host->name()->as_C_string(), NULL);
  5712     ClassLoader::package_from_name(unsafe_anonymous_host->name()->as_C_string(), NULL);
  5712 
  5713 
  5713   if (host_pkg_name != NULL) {
  5714   if (host_pkg_name != NULL) {
  5736 // exception.
  5737 // exception.
  5737 void ClassFileParser::fix_unsafe_anonymous_class_name(TRAPS) {
  5738 void ClassFileParser::fix_unsafe_anonymous_class_name(TRAPS) {
  5738   assert(_unsafe_anonymous_host != NULL, "Expected an unsafe anonymous class");
  5739   assert(_unsafe_anonymous_host != NULL, "Expected an unsafe anonymous class");
  5739 
  5740 
  5740   const jbyte* anon_last_slash = UTF8::strrchr((const jbyte*)_class_name->base(),
  5741   const jbyte* anon_last_slash = UTF8::strrchr((const jbyte*)_class_name->base(),
  5741                                                _class_name->utf8_length(), '/');
  5742                                                _class_name->utf8_length(), JVM_SIGNATURE_SLASH);
  5742   if (anon_last_slash == NULL) {  // Unnamed package
  5743   if (anon_last_slash == NULL) {  // Unnamed package
  5743     prepend_host_package_name(_unsafe_anonymous_host, CHECK);
  5744     prepend_host_package_name(_unsafe_anonymous_host, CHECK);
  5744   } else {
  5745   } else {
  5745     if (!_unsafe_anonymous_host->is_same_class_package(_unsafe_anonymous_host->class_loader(), _class_name)) {
  5746     if (!_unsafe_anonymous_host->is_same_class_package(_unsafe_anonymous_host->class_loader(), _class_name)) {
  5746       ResourceMark rm(THREAD);
  5747       ResourceMark rm(THREAD);
  6341 // return true if class_name contains no '.' (internal format is '/')
  6342 // return true if class_name contains no '.' (internal format is '/')
  6342 bool ClassFileParser::is_internal_format(Symbol* class_name) {
  6343 bool ClassFileParser::is_internal_format(Symbol* class_name) {
  6343   if (class_name != NULL) {
  6344   if (class_name != NULL) {
  6344     ResourceMark rm;
  6345     ResourceMark rm;
  6345     char* name = class_name->as_C_string();
  6346     char* name = class_name->as_C_string();
  6346     return strchr(name, '.') == NULL;
  6347     return strchr(name, JVM_SIGNATURE_DOT) == NULL;
  6347   } else {
  6348   } else {
  6348     return true;
  6349     return true;
  6349   }
  6350   }
  6350 }
  6351 }
  6351 
  6352