Mon, 09 Sep 2013 14:44:37 -0400
8023167: JVM allows duplicate Runtime[In]VisibleTypeAnnotations attributes in ClassFile/field_info/method_info structures
Summary: Add checks for duplicates and issue errors when detected.
Reviewed-by: coleenp, zgu
src/share/vm/classfile/classFileParser.cpp | file | annotate | diff | comparison | revisions |
1.1 --- a/src/share/vm/classfile/classFileParser.cpp Mon Sep 09 10:01:09 2013 +0100 1.2 +++ b/src/share/vm/classfile/classFileParser.cpp Mon Sep 09 14:44:37 2013 -0400 1.3 @@ -888,6 +888,7 @@ 1.4 int runtime_visible_type_annotations_length = 0; 1.5 u1* runtime_invisible_type_annotations = NULL; 1.6 int runtime_invisible_type_annotations_length = 0; 1.7 + bool runtime_invisible_type_annotations_exists = false; 1.8 while (attributes_count--) { 1.9 cfs->guarantee_more(6, CHECK); // attribute_name_index, attribute_length 1.10 u2 attribute_name_index = cfs->get_u2_fast(); 1.11 @@ -946,15 +947,27 @@ 1.12 assert(runtime_invisible_annotations != NULL, "null invisible annotations"); 1.13 cfs->skip_u1(runtime_invisible_annotations_length, CHECK); 1.14 } else if (attribute_name == vmSymbols::tag_runtime_visible_type_annotations()) { 1.15 + if (runtime_visible_type_annotations != NULL) { 1.16 + classfile_parse_error( 1.17 + "Multiple RuntimeVisibleTypeAnnotations attributes for field in class file %s", CHECK); 1.18 + } 1.19 runtime_visible_type_annotations_length = attribute_length; 1.20 runtime_visible_type_annotations = cfs->get_u1_buffer(); 1.21 assert(runtime_visible_type_annotations != NULL, "null visible type annotations"); 1.22 cfs->skip_u1(runtime_visible_type_annotations_length, CHECK); 1.23 - } else if (PreserveAllAnnotations && attribute_name == vmSymbols::tag_runtime_invisible_type_annotations()) { 1.24 - runtime_invisible_type_annotations_length = attribute_length; 1.25 - runtime_invisible_type_annotations = cfs->get_u1_buffer(); 1.26 - assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations"); 1.27 - cfs->skip_u1(runtime_invisible_type_annotations_length, CHECK); 1.28 + } else if (attribute_name == vmSymbols::tag_runtime_invisible_type_annotations()) { 1.29 + if (runtime_invisible_type_annotations_exists) { 1.30 + classfile_parse_error( 1.31 + "Multiple RuntimeInvisibleTypeAnnotations attributes for field in class file %s", CHECK); 1.32 + } else { 1.33 + runtime_invisible_type_annotations_exists = true; 1.34 + } 1.35 + if (PreserveAllAnnotations) { 1.36 + runtime_invisible_type_annotations_length = attribute_length; 1.37 + runtime_invisible_type_annotations = cfs->get_u1_buffer(); 1.38 + assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations"); 1.39 + } 1.40 + cfs->skip_u1(attribute_length, CHECK); 1.41 } else { 1.42 cfs->skip_u1(attribute_length, CHECK); // Skip unknown attributes 1.43 } 1.44 @@ -2060,6 +2073,7 @@ 1.45 int runtime_visible_type_annotations_length = 0; 1.46 u1* runtime_invisible_type_annotations = NULL; 1.47 int runtime_invisible_type_annotations_length = 0; 1.48 + bool runtime_invisible_type_annotations_exists = false; 1.49 u1* annotation_default = NULL; 1.50 int annotation_default_length = 0; 1.51 1.52 @@ -2316,16 +2330,30 @@ 1.53 assert(annotation_default != NULL, "null annotation default"); 1.54 cfs->skip_u1(annotation_default_length, CHECK_(nullHandle)); 1.55 } else if (method_attribute_name == vmSymbols::tag_runtime_visible_type_annotations()) { 1.56 + if (runtime_visible_type_annotations != NULL) { 1.57 + classfile_parse_error( 1.58 + "Multiple RuntimeVisibleTypeAnnotations attributes for method in class file %s", 1.59 + CHECK_(nullHandle)); 1.60 + } 1.61 runtime_visible_type_annotations_length = method_attribute_length; 1.62 runtime_visible_type_annotations = cfs->get_u1_buffer(); 1.63 assert(runtime_visible_type_annotations != NULL, "null visible type annotations"); 1.64 // No need for the VM to parse Type annotations 1.65 cfs->skip_u1(runtime_visible_type_annotations_length, CHECK_(nullHandle)); 1.66 - } else if (PreserveAllAnnotations && method_attribute_name == vmSymbols::tag_runtime_invisible_type_annotations()) { 1.67 - runtime_invisible_type_annotations_length = method_attribute_length; 1.68 - runtime_invisible_type_annotations = cfs->get_u1_buffer(); 1.69 - assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations"); 1.70 - cfs->skip_u1(runtime_invisible_type_annotations_length, CHECK_(nullHandle)); 1.71 + } else if (method_attribute_name == vmSymbols::tag_runtime_invisible_type_annotations()) { 1.72 + if (runtime_invisible_type_annotations_exists) { 1.73 + classfile_parse_error( 1.74 + "Multiple RuntimeInvisibleTypeAnnotations attributes for method in class file %s", 1.75 + CHECK_(nullHandle)); 1.76 + } else { 1.77 + runtime_invisible_type_annotations_exists = true; 1.78 + } 1.79 + if (PreserveAllAnnotations) { 1.80 + runtime_invisible_type_annotations_length = method_attribute_length; 1.81 + runtime_invisible_type_annotations = cfs->get_u1_buffer(); 1.82 + assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations"); 1.83 + } 1.84 + cfs->skip_u1(method_attribute_length, CHECK_(nullHandle)); 1.85 } else { 1.86 // Skip unknown attributes 1.87 cfs->skip_u1(method_attribute_length, CHECK_(nullHandle)); 1.88 @@ -2818,6 +2846,7 @@ 1.89 int runtime_visible_type_annotations_length = 0; 1.90 u1* runtime_invisible_type_annotations = NULL; 1.91 int runtime_invisible_type_annotations_length = 0; 1.92 + bool runtime_invisible_type_annotations_exists = false; 1.93 u1* inner_classes_attribute_start = NULL; 1.94 u4 inner_classes_attribute_length = 0; 1.95 u2 enclosing_method_class_index = 0; 1.96 @@ -2921,16 +2950,28 @@ 1.97 parsed_bootstrap_methods_attribute = true; 1.98 parse_classfile_bootstrap_methods_attribute(attribute_length, CHECK); 1.99 } else if (tag == vmSymbols::tag_runtime_visible_type_annotations()) { 1.100 + if (runtime_visible_type_annotations != NULL) { 1.101 + classfile_parse_error( 1.102 + "Multiple RuntimeVisibleTypeAnnotations attributes in class file %s", CHECK); 1.103 + } 1.104 runtime_visible_type_annotations_length = attribute_length; 1.105 runtime_visible_type_annotations = cfs->get_u1_buffer(); 1.106 assert(runtime_visible_type_annotations != NULL, "null visible type annotations"); 1.107 // No need for the VM to parse Type annotations 1.108 cfs->skip_u1(runtime_visible_type_annotations_length, CHECK); 1.109 - } else if (PreserveAllAnnotations && tag == vmSymbols::tag_runtime_invisible_type_annotations()) { 1.110 - runtime_invisible_type_annotations_length = attribute_length; 1.111 - runtime_invisible_type_annotations = cfs->get_u1_buffer(); 1.112 - assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations"); 1.113 - cfs->skip_u1(runtime_invisible_type_annotations_length, CHECK); 1.114 + } else if (tag == vmSymbols::tag_runtime_invisible_type_annotations()) { 1.115 + if (runtime_invisible_type_annotations_exists) { 1.116 + classfile_parse_error( 1.117 + "Multiple RuntimeInvisibleTypeAnnotations attributes in class file %s", CHECK); 1.118 + } else { 1.119 + runtime_invisible_type_annotations_exists = true; 1.120 + } 1.121 + if (PreserveAllAnnotations) { 1.122 + runtime_invisible_type_annotations_length = attribute_length; 1.123 + runtime_invisible_type_annotations = cfs->get_u1_buffer(); 1.124 + assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations"); 1.125 + } 1.126 + cfs->skip_u1(attribute_length, CHECK); 1.127 } else { 1.128 // Unknown attribute 1.129 cfs->skip_u1(attribute_length, CHECK);