8215407: javac should reject class files with bad EnclosingMethod attributes
authorjlahoda
Thu, 11 Apr 2019 14:49:04 +0200
changeset 54512 a84c46287f28
parent 54511 fbfcebad8e66
child 54513 2fd0422ac495
8215407: javac should reject class files with bad EnclosingMethod attributes Summary: Reject classfiles with broken EnclosingMethod attribute. Reviewed-by: jjg
src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java
test/langtools/tools/javac/classreader/8215407/BrokenEnclosingClass.java
test/langtools/tools/javac/classreader/8215407/Enclosing$1.jcod
test/langtools/tools/javac/classreader/8215407/UnrelatedClass.jcod
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Wed Apr 10 15:41:04 2019 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Thu Apr 11 14:49:04 2019 +0200
@@ -1502,6 +1502,10 @@
 
     // See java.lang.Class
     private Name simpleBinaryName(Name self, Name enclosing) {
+        if (!self.startsWith(enclosing)) {
+            throw badClassFile("bad.enclosing.method", self);
+        }
+
         String simpleBinaryName = self.toString().substring(enclosing.toString().length());
         if (simpleBinaryName.length() < 1 || simpleBinaryName.charAt(0) != '$')
             throw badClassFile("bad.enclosing.method", self);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/classreader/8215407/BrokenEnclosingClass.java	Thu Apr 11 14:49:04 2019 +0200
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2019, 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 8215407
+ * @summary Verify broken EnclosingMethod attribute does not break ClassReader.
+ * @library /tools/javac/lib
+ * @modules java.compiler
+ * @build JavacTestingAbstractProcessor
+ * @compile BrokenEnclosingClass.java UnrelatedClass.jcod Enclosing$1.jcod
+ * @compile -processor BrokenEnclosingClass BrokenEnclosingClass.java
+ */
+
+import java.util.Set;
+
+import javax.annotation.processing.RoundEnvironment;
+import javax.lang.model.element.TypeElement;
+
+public class BrokenEnclosingClass extends JavacTestingAbstractProcessor {
+
+    @Override
+    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+        if (processingEnv.getElementUtils().getTypeElement("UnrelatedClass") == null) {
+            throw new AssertionError("Cannot find UnrelatedClass.");
+        }
+        if (processingEnv.getElementUtils().getTypeElement("Enclosing$1") != null) {
+            throw new AssertionError("Enclosing$1 was found.");
+        }
+        return false;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/classreader/8215407/Enclosing$1.jcod	Thu Apr 11 14:49:04 2019 +0200
@@ -0,0 +1,91 @@
+class Enclosing$1 {
+  0xCAFEBABE;
+  0; // minor version
+  52; // version
+  [] { // Constant Pool
+    ; // first element is empty
+    Field #3 #16; // #1
+    Method #4 #17; // #2
+    class #18; // #3
+    class #20; // #4
+    Utf8 "this$0"; // #5
+    Utf8 "LUnrelatedClass;"; // #6
+    Utf8 "<init>"; // #7
+    Utf8 "(LUnrelatedClass;)V"; // #8
+    Utf8 "Code"; // #9
+    Utf8 "LineNumberTable"; // #10
+    Utf8 "SourceFile"; // #11
+    Utf8 "Enclosing.java"; // #12
+    Utf8 "EnclosingMethod"; // #13
+    class #21; // #14
+    NameAndType #22 #23; // #15
+    NameAndType #5 #6; // #16
+    NameAndType #7 #23; // #17
+    Utf8 "Enclosing$1"; // #18
+    Utf8 "InnerClasses"; // #19
+    Utf8 "java/lang/Object"; // #20
+    Utf8 "UnrelatedClass"; // #21
+    Utf8 "t"; // #22
+    Utf8 "()V"; // #23
+  } // Constant Pool
+
+  0x0020; // access
+  #3;// this_cpx
+  #4;// super_cpx
+
+  [] { // Interfaces
+  } // Interfaces
+
+  [] { // fields
+    { // Member
+      0x1010; // access
+      #5; // name_cpx
+      #6; // sig_cpx
+      [] { // Attributes
+      } // Attributes
+    } // Member
+  } // fields
+
+  [] { // methods
+    { // Member
+      0x0000; // access
+      #7; // name_cpx
+      #8; // sig_cpx
+      [] { // Attributes
+        Attr(#9) { // Code
+          2; // max_stack
+          2; // max_locals
+          Bytes[]{
+            0x2A2BB500012AB700;
+            0x02B1;
+          }
+          [] { // Traps
+          } // end Traps
+          [] { // Attributes
+            Attr(#10) { // LineNumberTable
+              [] { // LineNumberTable
+                0  3;
+              }
+            } // end LineNumberTable
+          } // Attributes
+        } // end Code
+      } // Attributes
+    } // Member
+  } // methods
+
+  [] { // Attributes
+    Attr(#11) { // SourceFile
+      #12;
+    } // end SourceFile
+    ;
+    Attr(#13) { // EnclosingMethod
+      #14; #15;
+    } // end EnclosingMethod
+    ;
+    Attr(#19) { // InnerClasses
+      [] { // InnerClasses
+        #3 #0 #0 0;
+      }
+    } // end InnerClasses
+  } // Attributes
+} // end class Enclosing$1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/classreader/8215407/UnrelatedClass.jcod	Thu Apr 11 14:49:04 2019 +0200
@@ -0,0 +1,101 @@
+class UnrelatedClass {
+  0xCAFEBABE;
+  0; // minor version
+  52; // version
+  [] { // Constant Pool
+    ; // first element is empty
+    Method #5 #14; // #1
+    class #15; // #2
+    Method #2 #16; // #3
+    class #17; // #4
+    class #18; // #5
+    Utf8 "InnerClasses"; // #6
+    Utf8 "<init>"; // #7
+    Utf8 "()V"; // #8
+    Utf8 "Code"; // #9
+    Utf8 "LineNumberTable"; // #10
+    Utf8 "t"; // #11
+    Utf8 "SourceFile"; // #12
+    Utf8 "Enclosing.java"; // #13
+    NameAndType #7 #8; // #14
+    Utf8 "Enclosing$1"; // #15
+    NameAndType #7 #19; // #16
+    Utf8 "UnrelatedClass"; // #17
+    Utf8 "java/lang/Object"; // #18
+    Utf8 "(LUnrelatedClass;)V"; // #19
+  } // Constant Pool
+
+  0x0021; // access
+  #4;// this_cpx
+  #5;// super_cpx
+
+  [] { // Interfaces
+  } // Interfaces
+
+  [] { // fields
+  } // fields
+
+  [] { // methods
+    { // Member
+      0x0001; // access
+      #7; // name_cpx
+      #8; // sig_cpx
+      [] { // Attributes
+        Attr(#9) { // Code
+          1; // max_stack
+          1; // max_locals
+          Bytes[]{
+            0x2AB70001B1;
+          }
+          [] { // Traps
+          } // end Traps
+          [] { // Attributes
+            Attr(#10) { // LineNumberTable
+              [] { // LineNumberTable
+                0  1;
+              }
+            } // end LineNumberTable
+          } // Attributes
+        } // end Code
+      } // Attributes
+    } // Member
+    ;
+    { // Member
+      0x0001; // access
+      #11; // name_cpx
+      #8; // sig_cpx
+      [] { // Attributes
+        Attr(#9) { // Code
+          3; // max_stack
+          1; // max_locals
+          Bytes[]{
+            0xBB0002592AB70003;
+            0x57B1;
+          }
+          [] { // Traps
+          } // end Traps
+          [] { // Attributes
+            Attr(#10) { // LineNumberTable
+              [] { // LineNumberTable
+                0  3;
+                9  4;
+              }
+            } // end LineNumberTable
+          } // Attributes
+        } // end Code
+      } // Attributes
+    } // Member
+  } // methods
+
+  [] { // Attributes
+    Attr(#12) { // SourceFile
+      #13;
+    } // end SourceFile
+    ;
+    Attr(#6) { // InnerClasses
+      [] { // InnerClasses
+        #2 #0 #0 0;
+      }
+    } // end InnerClasses
+  } // Attributes
+} // end class UnrelatedClass