1.1 --- a/src/share/vm/classfile/classFileParser.cpp Wed May 26 14:16:55 2010 -0700 1.2 +++ b/src/share/vm/classfile/classFileParser.cpp Thu May 27 17:06:39 2010 -0400 1.3 @@ -25,10 +25,10 @@ 1.4 #include "incls/_precompiled.incl" 1.5 #include "incls/_classFileParser.cpp.incl" 1.6 1.7 -// We generally try to create the oops directly when parsing, rather than allocating 1.8 -// temporary data structures and copying the bytes twice. A temporary area is only 1.9 -// needed when parsing utf8 entries in the constant pool and when parsing line number 1.10 -// tables. 1.11 +// We generally try to create the oops directly when parsing, rather than 1.12 +// allocating temporary data structures and copying the bytes twice. A 1.13 +// temporary area is only needed when parsing utf8 entries in the constant 1.14 +// pool and when parsing line number tables. 1.15 1.16 // We add assert in debug mode when class format is not checked. 1.17 1.18 @@ -47,6 +47,10 @@ 1.19 // - also used as the max version when running in jdk6 1.20 #define JAVA_6_VERSION 50 1.21 1.22 +// Used for backward compatibility reasons: 1.23 +// - to check NameAndType_info signatures more aggressively 1.24 +#define JAVA_7_VERSION 51 1.25 + 1.26 1.27 void ClassFileParser::parse_constant_pool_entries(constantPoolHandle cp, int length, TRAPS) { 1.28 // Use a local copy of ClassFileStream. It helps the C++ compiler to optimize 1.29 @@ -384,6 +388,20 @@ 1.30 verify_legal_class_name(class_name, CHECK_(nullHandle)); 1.31 break; 1.32 } 1.33 + case JVM_CONSTANT_NameAndType: { 1.34 + if (_need_verify && _major_version >= JAVA_7_VERSION) { 1.35 + int sig_index = cp->signature_ref_index_at(index); 1.36 + int name_index = cp->name_ref_index_at(index); 1.37 + symbolHandle name(THREAD, cp->symbol_at(name_index)); 1.38 + symbolHandle sig(THREAD, cp->symbol_at(sig_index)); 1.39 + if (sig->byte_at(0) == JVM_SIGNATURE_FUNC) { 1.40 + verify_legal_method_signature(name, sig, CHECK_(nullHandle)); 1.41 + } else { 1.42 + verify_legal_field_signature(name, sig, CHECK_(nullHandle)); 1.43 + } 1.44 + } 1.45 + break; 1.46 + } 1.47 case JVM_CONSTANT_Fieldref: 1.48 case JVM_CONSTANT_Methodref: 1.49 case JVM_CONSTANT_InterfaceMethodref: { 1.50 @@ -396,10 +414,28 @@ 1.51 symbolHandle signature(THREAD, cp->symbol_at(signature_ref_index)); 1.52 if (tag == JVM_CONSTANT_Fieldref) { 1.53 verify_legal_field_name(name, CHECK_(nullHandle)); 1.54 - verify_legal_field_signature(name, signature, CHECK_(nullHandle)); 1.55 + if (_need_verify && _major_version >= JAVA_7_VERSION) { 1.56 + // Signature is verified above, when iterating NameAndType_info. 1.57 + // Need only to be sure it's the right type. 1.58 + if (signature->byte_at(0) == JVM_SIGNATURE_FUNC) { 1.59 + throwIllegalSignature( 1.60 + "Field", name, signature, CHECK_(nullHandle)); 1.61 + } 1.62 + } else { 1.63 + verify_legal_field_signature(name, signature, CHECK_(nullHandle)); 1.64 + } 1.65 } else { 1.66 verify_legal_method_name(name, CHECK_(nullHandle)); 1.67 - verify_legal_method_signature(name, signature, CHECK_(nullHandle)); 1.68 + if (_need_verify && _major_version >= JAVA_7_VERSION) { 1.69 + // Signature is verified above, when iterating NameAndType_info. 1.70 + // Need only to be sure it's the right type. 1.71 + if (signature->byte_at(0) != JVM_SIGNATURE_FUNC) { 1.72 + throwIllegalSignature( 1.73 + "Method", name, signature, CHECK_(nullHandle)); 1.74 + } 1.75 + } else { 1.76 + verify_legal_method_signature(name, signature, CHECK_(nullHandle)); 1.77 + } 1.78 if (tag == JVM_CONSTANT_Methodref) { 1.79 // 4509014: If a class method name begins with '<', it must be "<init>". 1.80 assert(!name.is_null(), "method name in constant pool is null"); 1.81 @@ -1313,6 +1349,14 @@ 1.82 return checked_exceptions_start; 1.83 } 1.84 1.85 +void ClassFileParser::throwIllegalSignature( 1.86 + const char* type, symbolHandle name, symbolHandle sig, TRAPS) { 1.87 + ResourceMark rm(THREAD); 1.88 + Exceptions::fthrow(THREAD_AND_LOCATION, 1.89 + vmSymbols::java_lang_ClassFormatError(), 1.90 + "%s \"%s\" in class %s has illegal signature \"%s\"", type, 1.91 + name->as_C_string(), _class_name->as_C_string(), sig->as_C_string()); 1.92 +} 1.93 1.94 #define MAX_ARGS_SIZE 255 1.95 #define MAX_CODE_SIZE 65535 1.96 @@ -4058,14 +4102,7 @@ 1.97 char* p = skip_over_field_signature(bytes, false, length, CHECK); 1.98 1.99 if (p == NULL || (p - bytes) != (int)length) { 1.100 - ResourceMark rm(THREAD); 1.101 - Exceptions::fthrow( 1.102 - THREAD_AND_LOCATION, 1.103 - vmSymbolHandles::java_lang_ClassFormatError(), 1.104 - "Field \"%s\" in class %s has illegal signature \"%s\"", 1.105 - name->as_C_string(), _class_name->as_C_string(), bytes 1.106 - ); 1.107 - return; 1.108 + throwIllegalSignature("Field", name, signature, CHECK); 1.109 } 1.110 } 1.111 1.112 @@ -4116,13 +4153,7 @@ 1.113 } 1.114 } 1.115 // Report error 1.116 - ResourceMark rm(THREAD); 1.117 - Exceptions::fthrow( 1.118 - THREAD_AND_LOCATION, 1.119 - vmSymbolHandles::java_lang_ClassFormatError(), 1.120 - "Method \"%s\" in class %s has illegal signature \"%s\"", 1.121 - name->as_C_string(), _class_name->as_C_string(), p 1.122 - ); 1.123 + throwIllegalSignature("Method", name, signature, CHECK_0); 1.124 return 0; 1.125 } 1.126