src/share/vm/classfile/classFileParser.cpp

Print this page

        

*** 2313,2329 **** // Inner classes can be static, private or protected (classic VM does this) #define RECOGNIZED_INNER_CLASS_MODIFIERS (JVM_RECOGNIZED_CLASS_MODIFIERS | JVM_ACC_PRIVATE | JVM_ACC_PROTECTED | JVM_ACC_STATIC) // Return number of classes in the inner classes attribute table ! u2 ClassFileParser::parse_classfile_inner_classes_attribute(constantPoolHandle cp, instanceKlassHandle k, TRAPS) { ClassFileStream* cfs = stream(); cfs->guarantee_more(2, CHECK_0); // length ! u2 length = cfs->get_u2_fast(); ! // 4-tuples of shorts [inner_class_info_index, outer_class_info_index, inner_name_index, inner_class_access_flags] ! typeArrayOop ic = oopFactory::new_permanent_shortArray(length*4, CHECK_0); typeArrayHandle inner_classes(THREAD, ic); int index = 0; int cp_size = cp->length(); cfs->guarantee_more(8 * length, CHECK_0); // 4-tuples of u2 for (int n = 0; n < length; n++) { --- 2313,2348 ---- // Inner classes can be static, private or protected (classic VM does this) #define RECOGNIZED_INNER_CLASS_MODIFIERS (JVM_RECOGNIZED_CLASS_MODIFIERS | JVM_ACC_PRIVATE | JVM_ACC_PROTECTED | JVM_ACC_STATIC) // Return number of classes in the inner classes attribute table ! u2 ClassFileParser::parse_classfile_inner_classes_attribute(u1* inner_classes_attribute_start, ! bool parsed_enclosingmethod_attribute, ! u2 enclosing_method_class_index, ! u2 enclosing_method_method_index, ! constantPoolHandle cp, ! instanceKlassHandle k, TRAPS) { ClassFileStream* cfs = stream(); + u1* current_mark = cfs->current(); + u2 length = 0; + if (inner_classes_attribute_start != NULL) { + cfs->set_current(inner_classes_attribute_start); cfs->guarantee_more(2, CHECK_0); // length ! length = cfs->get_u2_fast(); ! } ! // 4-tuples of shorts of inner classes data and 2 shorts of enclosing ! // method data: ! // [inner_class_info_index, ! // outer_class_info_index, ! // inner_name_index, ! // inner_class_access_flags, ! // ... ! // enclosing_method_class_index, ! // enclosing_method_method_index] ! u2 size = length * 4 + (parsed_enclosingmethod_attribute ? 2 : 0); ! typeArrayOop ic = oopFactory::new_permanent_shortArray(size, CHECK_0); typeArrayHandle inner_classes(THREAD, ic); int index = 0; int cp_size = cp->length(); cfs->guarantee_more(8 * length, CHECK_0); // 4-tuples of u2 for (int n = 0; n < length; n++) {
*** 2382,2393 **** --- 2401,2422 ---- CHECK_0); } } } + // Set EnclosingMethod class and method indexes. + if (parsed_enclosingmethod_attribute) { + inner_classes->short_at_put(index++, enclosing_method_class_index); + inner_classes->short_at_put(index++, enclosing_method_method_index); + } + // Update instanceKlass with inner class info. k->set_inner_classes(inner_classes()); + + // Restore buffer's current position. + cfs->set_current(current_mark); + return length; } void ClassFileParser::parse_classfile_synthetic_attribute(constantPoolHandle cp, instanceKlassHandle k, TRAPS) { k->set_is_synthetic();
*** 2488,2497 **** --- 2517,2530 ---- bool parsed_bootstrap_methods_attribute = false; u1* runtime_visible_annotations = NULL; int runtime_visible_annotations_length = 0; u1* runtime_invisible_annotations = NULL; int runtime_invisible_annotations_length = 0; + u1* inner_classes_attribute_start = NULL; + u4 inner_classes_attribute_length = 0; + u2 enclosing_method_class_index = 0; + u2 enclosing_method_method_index = 0; // Iterate over attributes while (attributes_count--) { cfs->guarantee_more(6, CHECK); // attribute_name_index, attribute_length u2 attribute_name_index = cfs->get_u2_fast(); u4 attribute_length = cfs->get_u4_fast();
*** 2520,2534 **** if (parsed_innerclasses_attribute) { classfile_parse_error("Multiple InnerClasses attributes in class file %s", CHECK); } else { parsed_innerclasses_attribute = true; } ! u2 num_of_classes = parse_classfile_inner_classes_attribute(cp, k, CHECK); ! if (_need_verify && _major_version >= JAVA_1_5_VERSION) { ! guarantee_property(attribute_length == sizeof(num_of_classes) + 4 * sizeof(u2) * num_of_classes, ! "Wrong InnerClasses attribute length in class file %s", CHECK); ! } } else if (tag == vmSymbols::tag_synthetic()) { // Check for Synthetic tag // Shouldn't we check that the synthetic flags wasn't already set? - not required in spec if (attribute_length != 0) { classfile_parse_error( --- 2553,2565 ---- if (parsed_innerclasses_attribute) { classfile_parse_error("Multiple InnerClasses attributes in class file %s", CHECK); } else { parsed_innerclasses_attribute = true; } ! inner_classes_attribute_start = cfs->get_u1_buffer(); ! inner_classes_attribute_length = attribute_length; ! cfs->skip_u1(inner_classes_attribute_length, CHECK); } else if (tag == vmSymbols::tag_synthetic()) { // Check for Synthetic tag // Shouldn't we check that the synthetic flags wasn't already set? - not required in spec if (attribute_length != 0) { classfile_parse_error(
*** 2566,2591 **** classfile_parse_error("Multiple EnclosingMethod attributes in class file %s", CHECK); } else { parsed_enclosingmethod_attribute = true; } cfs->guarantee_more(4, CHECK); // class_index, method_index ! u2 class_index = cfs->get_u2_fast(); ! u2 method_index = cfs->get_u2_fast(); ! if (class_index == 0) { classfile_parse_error("Invalid class index in EnclosingMethod attribute in class file %s", CHECK); } // Validate the constant pool indices and types ! if (!cp->is_within_bounds(class_index) || ! !is_klass_reference(cp, class_index)) { classfile_parse_error("Invalid or out-of-bounds class index in EnclosingMethod attribute in class file %s", CHECK); } ! if (method_index != 0 && ! (!cp->is_within_bounds(method_index) || ! !cp->tag_at(method_index).is_name_and_type())) { classfile_parse_error("Invalid or out-of-bounds method index in EnclosingMethod attribute in class file %s", CHECK); } - k->set_enclosing_method_indices(class_index, method_index); } else if (tag == vmSymbols::tag_bootstrap_methods() && _major_version >= Verifier::INVOKEDYNAMIC_MAJOR_VERSION) { if (parsed_bootstrap_methods_attribute) classfile_parse_error("Multiple BootstrapMethods attributes in class file %s", CHECK); parsed_bootstrap_methods_attribute = true; --- 2597,2621 ---- classfile_parse_error("Multiple EnclosingMethod attributes in class file %s", CHECK); } else { parsed_enclosingmethod_attribute = true; } cfs->guarantee_more(4, CHECK); // class_index, method_index ! enclosing_method_class_index = cfs->get_u2_fast(); ! enclosing_method_method_index = cfs->get_u2_fast(); ! if (enclosing_method_class_index == 0) { classfile_parse_error("Invalid class index in EnclosingMethod attribute in class file %s", CHECK); } // Validate the constant pool indices and types ! if (!cp->is_within_bounds(enclosing_method_class_index) || ! !is_klass_reference(cp, enclosing_method_class_index)) { classfile_parse_error("Invalid or out-of-bounds class index in EnclosingMethod attribute in class file %s", CHECK); } ! if (enclosing_method_method_index != 0 && ! (!cp->is_within_bounds(enclosing_method_method_index) || ! !cp->tag_at(enclosing_method_method_index).is_name_and_type())) { classfile_parse_error("Invalid or out-of-bounds method index in EnclosingMethod attribute in class file %s", CHECK); } } else if (tag == vmSymbols::tag_bootstrap_methods() && _major_version >= Verifier::INVOKEDYNAMIC_MAJOR_VERSION) { if (parsed_bootstrap_methods_attribute) classfile_parse_error("Multiple BootstrapMethods attributes in class file %s", CHECK); parsed_bootstrap_methods_attribute = true;
*** 2604,2613 **** --- 2634,2655 ---- runtime_invisible_annotations, runtime_invisible_annotations_length, CHECK); k->set_class_annotations(annotations()); + if (parsed_innerclasses_attribute || parsed_enclosingmethod_attribute) { + u2 num_of_classes = parse_classfile_inner_classes_attribute( + inner_classes_attribute_start, parsed_innerclasses_attribute, + enclosing_method_class_index, enclosing_method_method_index, + cp, k, CHECK); + if (parsed_innerclasses_attribute &&_need_verify && _major_version >= JAVA_1_5_VERSION) { + guarantee_property( + inner_classes_attribute_length == sizeof(num_of_classes) + 4 * sizeof(u2) * num_of_classes, + "Wrong InnerClasses attribute length in class file %s", CHECK); + } + } + if (_max_bootstrap_specifier_index >= 0) { guarantee_property(parsed_bootstrap_methods_attribute, "Missing BootstrapMethods attribute in class file %s", CHECK); } }