src/share/vm/classfile/classFileParser.cpp

changeset 1941
086d73ccd6c0
parent 1868
df736661d0c8
child 1944
3a9de63b2209
     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  

mercurial