Don't assert if class has a bad element_tag in an element_value structure of a RuntimeVisibleAnnotation attribute.  Instead, ignore the attribute.

Reviewed-by: acorn, gtriantafill
This commit is contained in:
Harold Seigel 2015-06-18 08:44:28 -04:00
parent f6fac96205
commit 058dd16f78
4 changed files with 180 additions and 11 deletions

View file

@ -949,8 +949,7 @@ void ClassFileParser::parse_field_attributes(u2 attributes_count,
assert(runtime_visible_annotations != NULL, "null visible annotations"); assert(runtime_visible_annotations != NULL, "null visible annotations");
parse_annotations(runtime_visible_annotations, parse_annotations(runtime_visible_annotations,
runtime_visible_annotations_length, runtime_visible_annotations_length,
parsed_annotations, parsed_annotations);
CHECK);
cfs->skip_u1(runtime_visible_annotations_length, CHECK); cfs->skip_u1(runtime_visible_annotations_length, CHECK);
} else if (attribute_name == vmSymbols::tag_runtime_invisible_annotations()) { } else if (attribute_name == vmSymbols::tag_runtime_invisible_annotations()) {
if (runtime_invisible_annotations_exists) { if (runtime_invisible_annotations_exists) {
@ -1643,7 +1642,6 @@ int ClassFileParser::skip_annotation_value(u1* buffer, int limit, int index) {
index = skip_annotation(buffer, limit, index); index = skip_annotation(buffer, limit, index);
break; break;
default: default:
assert(false, "annotation tag");
return limit; // bad tag byte return limit; // bad tag byte
} }
return index; return index;
@ -1651,8 +1649,7 @@ int ClassFileParser::skip_annotation_value(u1* buffer, int limit, int index) {
// Sift through annotations, looking for those significant to the VM: // Sift through annotations, looking for those significant to the VM:
void ClassFileParser::parse_annotations(u1* buffer, int limit, void ClassFileParser::parse_annotations(u1* buffer, int limit,
ClassFileParser::AnnotationCollector* coll, ClassFileParser::AnnotationCollector* coll) {
TRAPS) {
// annotations := do(nann:u2) {annotation} // annotations := do(nann:u2) {annotation}
int index = 0; int index = 0;
if ((index += 2) >= limit) return; // read nann if ((index += 2) >= limit) return; // read nann
@ -2280,8 +2277,7 @@ methodHandle ClassFileParser::parse_method(bool is_interface,
runtime_visible_annotations = cfs->get_u1_buffer(); runtime_visible_annotations = cfs->get_u1_buffer();
assert(runtime_visible_annotations != NULL, "null visible annotations"); assert(runtime_visible_annotations != NULL, "null visible annotations");
parse_annotations(runtime_visible_annotations, parse_annotations(runtime_visible_annotations,
runtime_visible_annotations_length, &parsed_annotations, runtime_visible_annotations_length, &parsed_annotations);
CHECK_(nullHandle));
cfs->skip_u1(runtime_visible_annotations_length, CHECK_(nullHandle)); cfs->skip_u1(runtime_visible_annotations_length, CHECK_(nullHandle));
} else if (method_attribute_name == vmSymbols::tag_runtime_invisible_annotations()) { } else if (method_attribute_name == vmSymbols::tag_runtime_invisible_annotations()) {
if (runtime_invisible_annotations_exists) { if (runtime_invisible_annotations_exists) {
@ -2945,8 +2941,7 @@ void ClassFileParser::parse_classfile_attributes(ClassFileParser::ClassAnnotatio
assert(runtime_visible_annotations != NULL, "null visible annotations"); assert(runtime_visible_annotations != NULL, "null visible annotations");
parse_annotations(runtime_visible_annotations, parse_annotations(runtime_visible_annotations,
runtime_visible_annotations_length, runtime_visible_annotations_length,
parsed_annotations, parsed_annotations);
CHECK);
cfs->skip_u1(runtime_visible_annotations_length, CHECK); cfs->skip_u1(runtime_visible_annotations_length, CHECK);
} else if (tag == vmSymbols::tag_runtime_invisible_annotations()) { } else if (tag == vmSymbols::tag_runtime_invisible_annotations()) {
if (runtime_invisible_annotations_exists) { if (runtime_invisible_annotations_exists) {

View file

@ -294,8 +294,7 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
int skip_annotation_value(u1* buffer, int limit, int index); int skip_annotation_value(u1* buffer, int limit, int index);
void parse_annotations(u1* buffer, int limit, void parse_annotations(u1* buffer, int limit,
/* Results (currently, only one result is supported): */ /* Results (currently, only one result is supported): */
AnnotationCollector* result, AnnotationCollector* result);
TRAPS);
// Final setup // Final setup
unsigned int compute_oop_map_count(instanceKlassHandle super, unsigned int compute_oop_map_count(instanceKlassHandle super,

View file

@ -0,0 +1,46 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
/*
* @test
* @bug 8042041
* @summary Fuzzy-ed RuntimeVisibleAnnotations causes assertion
* @compile badAnnotTag.jcod
* @run main AnnotationTag
*/
// Test that a bad element_tag in an element_value of a RuntimeVisibileAnnotation
// attribute is ignored.
public class AnnotationTag {
public static void main(String args[]) throws Throwable {
System.out.println("Regression test for bug 8042041");
try {
Class newClass = Class.forName("badAnnotTag");
} catch (java.lang.Throwable e) {
throw new RuntimeException(
"Unexpected exception: " + e.getMessage());
}
}
}

View file

@ -0,0 +1,129 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
// This class contains a bad element_tag in an element_value structure for a
// RuntimeVisibleAnnotation at line 91. The bad element tag should be ignored
// by the class file parser.
class badAnnotTag {
0xCAFEBABE;
0; // minor version
52; // version
[19] { // Constant Pool
; // first element is empty
class #16; // #1 at 0x0A
class #17; // #2 at 0x0D
class #18; // #3 at 0x10
Utf8 "value"; // #4 at 0x13
Utf8 "()Ljava/lang/String;"; // #5 at 0x1B
Utf8 "SourceFile"; // #6 at 0x32
Utf8 "badAnnotTag.java"; // #7 at 0x3F
Utf8 "RuntimeVisibleAnnotations"; // #8 at 0x50
Utf8 "Ljava/lang/annotation/Target;"; // #9 at 0x6C
Utf8 "Ljava/lang/annotation/ElementType;"; // #10 at 0x8C
Utf8 "TYPE_USE"; // #11 at 0xB1
Utf8 "TYPE_PARAMETER"; // #12 at 0xBC
Utf8 "Ljava/lang/annotation/Retention;"; // #13 at 0xCD
Utf8 "Ljava/lang/annotation/RetentionPolicy;"; // #14 at 0xF0
Utf8 "RUNTIME"; // #15 at 0x0119
Utf8 "badAnnotTag"; // #16 at 0x0123
Utf8 "java/lang/Object"; // #17 at 0x0127
Utf8 "java/lang/annotation/Annotation"; // #18 at 0x013A
} // Constant Pool
0x2600; // access
#1;// this_cpx
#2;// super_cpx
[1] { // Interfaces
#3;
} // Interfaces
[0] { // fields
} // fields
[1] { // methods
{ // Member at 0x016A
0x0401; // access
#4; // name_cpx
#5; // sig_cpx
[0] { // Attributes
} // Attributes
} // Member
} // methods
[2] { // Attributes
Attr(#6, 2) { // SourceFile at 0x0174
#7;
} // end SourceFile
;
Attr(#8, 32) { // RuntimeVisibleAnnotations at 0x017C
[2] { // annotations
{ // annotation
#9;
[1] { // element_value_pairs
{ // element value pair
#4;
{ // element_value
'[';
[2] { // array_value
{ // element_value
'd'; // * illegal value *, correct value is 'e'
{ // enum_const_value
#10;
#11;
} // enum_const_value
} // element_value
;
{ // element_value
'e';
{ // enum_const_value
#10;
#12;
} // enum_const_value
} // element_value
} // array_value
} // element_value
} // element value pair
} // element_value_pairs
} // annotation
;
{ // annotation
#13;
[1] { // element_value_pairs
{ // element value pair
#4;
{ // element_value
'e';
{ // enum_const_value
#14;
#15;
} // enum_const_value
} // element_value
} // element value pair
} // element_value_pairs
} // annotation
}
} // end RuntimeVisibleAnnotations
} // Attributes
} // end class badAnnotTag