--- old/src/share/vm/classfile/classFileParser.cpp 2016-09-01 17:00:24.549214777 -0400 +++ new/src/share/vm/classfile/classFileParser.cpp 2016-09-01 17:00:24.261214787 -0400 @@ -95,7 +95,6 @@ #define JAVA_6_VERSION 50 // Used for backward compatibility reasons: -// - to check NameAndType_info signatures more aggressively // - to disallow argument and require ACC_STATIC for methods #define JAVA_7_VERSION 51 @@ -564,7 +563,7 @@ break; } case JVM_CONSTANT_NameAndType: { - if (_need_verify && _major_version >= JAVA_7_VERSION) { + if (_need_verify) { const int sig_index = cp->signature_ref_index_at(index); const int name_index = cp->name_ref_index_at(index); const Symbol* const name = cp->symbol_at(name_index); @@ -572,9 +571,17 @@ guarantee_property(sig->utf8_length() != 0, "Illegal zero length constant pool entry at %d in class %s", sig_index, CHECK); + guarantee_property(name->utf8_length() != 0, + "Illegal zero length constant pool entry at %d in class %s", + name_index, CHECK); + if (sig->byte_at(0) == JVM_SIGNATURE_FUNC) { + // Format check Methodref name and signature + verify_legal_method_name(name, CHECK); verify_legal_method_signature(name, sig, CHECK); } else { + // Format check Fieldref name and signature + verify_legal_field_name(name, CHECK); verify_legal_field_signature(name, sig, CHECK); } } @@ -595,42 +602,32 @@ const Symbol* const name = cp->symbol_at(name_ref_index); const Symbol* const signature = cp->symbol_at(signature_ref_index); if (tag == JVM_CONSTANT_Fieldref) { - verify_legal_field_name(name, CHECK); - if (_need_verify && _major_version >= JAVA_7_VERSION) { - // Signature is verified above, when iterating NameAndType_info. - // Need only to be sure it's non-zero length and the right type. + if (_need_verify) { + // Field name and signature are verified above, when iterating NameAndType_info. + // Need only to be sure signature is non-zero length and the right type. if (signature->utf8_length() == 0 || signature->byte_at(0) == JVM_SIGNATURE_FUNC) { - throwIllegalSignature( - "Field", name, signature, CHECK); + throwIllegalSignature("Field", name, signature, CHECK); } - } else { - verify_legal_field_signature(name, signature, CHECK); } } else { - verify_legal_method_name(name, CHECK); - if (_need_verify && _major_version >= JAVA_7_VERSION) { - // Signature is verified above, when iterating NameAndType_info. - // Need only to be sure it's non-zero length and the right type. + if (_need_verify) { + // Method name and signature are verified above, when iterating NameAndType_info. + // Need only to be sure signature is non-zero length and the right type. if (signature->utf8_length() == 0 || signature->byte_at(0) != JVM_SIGNATURE_FUNC) { - throwIllegalSignature( - "Method", name, signature, CHECK); + throwIllegalSignature("Method", name, signature, CHECK); } - } else { - verify_legal_method_signature(name, signature, CHECK); } - if (tag == JVM_CONSTANT_Methodref) { - // 4509014: If a class method name begins with '<', it must be "". - assert(name != NULL, "method name in constant pool is null"); - const unsigned int name_len = name->utf8_length(); - if (name_len != 0 && name->byte_at(0) == '<') { - if (name != vmSymbols::object_initializer_name()) { - classfile_parse_error( - "Bad method name at constant pool index %u in class file %s", - name_ref_index, CHECK); - } - } + // 4509014: If a class method name begins with '<', it must be "" + const unsigned int name_len = name->utf8_length(); + if (tag == JVM_CONSTANT_Methodref && + name_len != 0 && + name->byte_at(0) == '<' && + name != vmSymbols::object_initializer_name()) { + classfile_parse_error( + "Bad method name at constant pool index %u in class file %s", + name_ref_index, CHECK); } } break; @@ -4843,19 +4840,28 @@ } } else { - // 4900761: For class version > 48, any unicode is allowed in class name. + // Skip leading 'L' and ignore first appearance of ';' length--; signature++; - while (length > 0 && signature[0] != ';') { - if (signature[0] == '.') { - classfile_parse_error("Class name contains illegal character '.' in descriptor in class file %s", CHECK_0); + char* c = strchr((char*) signature, ';'); + // Format check signature + if (c != NULL) { + int newlen = c - (char*) signature; + char* sig = NEW_RESOURCE_ARRAY(char, newlen + 1); + strncpy(sig, signature, newlen); + sig[newlen] = '\0'; + + bool legal = verify_unqualified_name(sig, newlen, LegalClass); + if (!legal) { + ResourceMark rm(THREAD); + classfile_parse_error("Class name contains illegal character " + "in descriptor in class file %s", + CHECK_0); + return NULL; } - length--; - signature++; + return signature + newlen + 1; } - if (signature[0] == ';') { return signature + 1; } } - return NULL; } case JVM_SIGNATURE_ARRAY: @@ -4869,7 +4875,6 @@ length--; void_ok = false; break; - default: return NULL; }