8207944: java.lang.ClassFormatError: Extra bytes at the end of class file test" possibly violation of JVMS 4.7.1
authorhseigel
Thu, 26 Jul 2018 15:56:37 -0400
changeset 51297 9d49099287b1
parent 51296 d64013e38c11
child 51298 3e08503ad77e
8207944: java.lang.ClassFormatError: Extra bytes at the end of class file test" possibly violation of JVMS 4.7.1 Summary: Add code to skip over unknown attributes when class file version >= 11. Reviewed-by: lfoltan
src/hotspot/share/classfile/classFileParser.cpp
test/hotspot/jtreg/runtime/classFileParserBug/UnknownAttr.jcod
test/hotspot/jtreg/runtime/classFileParserBug/UnknownAttrTest.java
--- a/src/hotspot/share/classfile/classFileParser.cpp	Thu Jul 26 11:53:59 2018 -0700
+++ b/src/hotspot/share/classfile/classFileParser.cpp	Thu Jul 26 15:56:37 2018 -0400
@@ -3570,6 +3570,9 @@
                          "Nest-host class_info_index %u has bad constant type in class file %s",
                          class_info_index, CHECK);
           _nest_host = class_info_index;
+        } else {
+          // Unknown attribute
+          cfs->skip_u1(attribute_length, CHECK);
         }
       } else {
         // Unknown attribute
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/classFileParserBug/UnknownAttr.jcod	Thu Jul 26 15:56:37 2018 -0400
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2018, 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 has an unknown attribute called UnknownAttr.Added.  The
+// attribute should be ignored by the JVM.
+//
+class UnknownAttr { 
+  0xCAFEBABE; 
+  0; // minor version 
+  55; // version 
+  [] { // Constant Pool 
+    ; // first element is empty 
+    class #2; // #1 
+    Utf8 "UnknownAttr"; // #2 
+    class #4; // #3 
+    Utf8 "java/lang/Object"; // #4 
+    Utf8 "<init>"; // #5 
+    Utf8 "()V"; // #6 
+    Utf8 "Code"; // #7 
+    Method #3 #9; // #8 
+    NameAndType #5 #6; // #9 
+    Utf8 "main"; // #10 
+    Utf8 "([Ljava/lang/String;)V"; // #11 
+    Utf8 "UnknownAttr.Added"; // #12 
+  } // Constant Pool 
+
+  0x0021; // access 
+  #1;// this_cpx 
+  #3;// super_cpx 
+
+  [] { // Interfaces 
+  } // Interfaces 
+
+  [] { // fields 
+  } // fields 
+
+  [] { // methods 
+    { // Member 
+      0x0001; // access 
+      #5; // name_cpx 
+      #6; // sig_cpx 
+      [] { // Attributes 
+        Attr(#7) { // Code 
+          1; // max_stack 
+          1; // max_locals 
+          Bytes[]{ 
+            0x2AB70008B1; 
+          } 
+          [] { // Traps 
+          } // end Traps 
+          [] { // Attributes 
+          } // Attributes 
+        } // end Code 
+      } // Attributes 
+    } // Member 
+    ; 
+    { // Member 
+      0x0009; // access 
+      #10; // name_cpx 
+      #11; // sig_cpx 
+      [] { // Attributes 
+        Attr(#7) { // Code 
+          0; // max_stack 
+          1; // max_locals 
+          Bytes[]{ 
+            0xB1; 
+          } 
+          [] { // Traps 
+          } // end Traps 
+          [] { // Attributes 
+          } // Attributes 
+        } // end Code 
+      } // Attributes 
+    } // Member 
+  } // methods 
+
+  [] { // Attributes 
+    Attr(#12) { // UnknownAttr.Added 
+      0x00; 
+    } // end UnknownAttr.Added 
+  } // Attributes 
+} // end class UnknownAttr
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/classFileParserBug/UnknownAttrTest.java	Thu Jul 26 15:56:37 2018 -0400
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2018, 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 8207944
+ * @summary Unknown attribute erroneously causes ClassFormatError exception.
+ * @compile UnknownAttr.jcod
+ * @run main UnknownAttrTest
+ */
+
+// Test that an unknown class attribute is ignored and no exception is thrown.
+public class UnknownAttrTest {
+    public static void main(String args[]) throws Throwable {
+
+        System.out.println("Regression test for bug 8207944");
+        try {
+            Class newClass = Class.forName("UnknownAttr");
+        } catch (java.lang.Throwable e) {
+            throw new RuntimeException(
+                "Unexpected exception: " + e.getMessage());
+        }
+    }
+}