8038023: Compiler crash ClassCastException
authorpgovereau
Tue, 22 Apr 2014 19:52:15 +0100
changeset 24068 d8a1180faaa9
parent 24067 76e7b6bbbd85
child 24069 dfb8f11542fc
8038023: Compiler crash ClassCastException Summary: Add additional checks on results of ClassReader.readPool Reviewed-by: vromero
langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java
langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties
langtools/test/tools/javac/diags/examples.not-yet.txt
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Tue Apr 22 16:51:10 2014 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Tue Apr 22 19:52:15 2014 +0100
@@ -475,14 +475,14 @@
             break;
         case CONSTANT_Fieldref: {
             ClassSymbol owner = readClassSymbol(getChar(index + 1));
-            NameAndType nt = (NameAndType)readPool(getChar(index + 3));
+            NameAndType nt = readNameAndType(getChar(index + 3));
             poolObj[i] = new VarSymbol(0, nt.name, nt.uniqueType.type, owner);
             break;
         }
         case CONSTANT_Methodref:
         case CONSTANT_InterfaceMethodref: {
             ClassSymbol owner = readClassSymbol(getChar(index + 1));
-            NameAndType nt = (NameAndType)readPool(getChar(index + 3));
+            NameAndType nt = readNameAndType(getChar(index + 3));
             poolObj[i] = new MethodSymbol(0, nt.name, nt.uniqueType.type, owner);
             break;
         }
@@ -551,13 +551,34 @@
     /** Read class entry.
      */
     ClassSymbol readClassSymbol(int i) {
-        return (ClassSymbol) (readPool(i));
+        Object obj = readPool(i);
+        if (obj != null && !(obj instanceof ClassSymbol))
+            throw badClassFile("bad.const.pool.entry",
+                               currentClassFile.toString(),
+                               "CONSTANT_Class_info", i);
+        return (ClassSymbol)obj;
     }
 
     /** Read name.
      */
     Name readName(int i) {
-        return (Name) (readPool(i));
+        Object obj = readPool(i);
+        if (obj != null && !(obj instanceof Name))
+            throw badClassFile("bad.const.pool.entry",
+                               currentClassFile.toString(),
+                               "CONSTANT_Utf8_info or CONSTANT_String_info", i);
+        return (Name)obj;
+    }
+
+    /** Read name and type.
+     */
+    NameAndType readNameAndType(int i) {
+        Object obj = readPool(i);
+        if (obj != null && !(obj instanceof NameAndType))
+            throw badClassFile("bad.const.pool.entry",
+                               currentClassFile.toString(),
+                               "CONSTANT_NameAndType_info", i);
+        return (NameAndType)obj;
     }
 
 /************************************************************************
@@ -1209,7 +1230,7 @@
         sym.owner.members().remove(sym);
         ClassSymbol self = (ClassSymbol)sym;
         ClassSymbol c = readClassSymbol(nextChar());
-        NameAndType nt = (NameAndType)readPool(nextChar());
+        NameAndType nt = readNameAndType(nextChar());
 
         if (c.members_field == null)
             throw badClassFile("bad.enclosing.class", self, c);
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Tue Apr 22 16:51:10 2014 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Tue Apr 22 19:52:15 2014 +0100
@@ -1719,6 +1719,11 @@
 compiler.misc.bad.class.file=\
     class file is invalid for class {0}
 
+# 0: file name, 1: expected CP entry type, 2: constant pool index
+compiler.misc.bad.const.pool.entry=\
+    bad constant pool entry in {0}\n\
+    expected {1} at index {2}
+
 # 0: file name, 1: message segment
 compiler.misc.bad.class.file.header=\
     bad class file: {0}\n\
--- a/langtools/test/tools/javac/diags/examples.not-yet.txt	Tue Apr 22 16:51:10 2014 +0200
+++ b/langtools/test/tools/javac/diags/examples.not-yet.txt	Tue Apr 22 19:52:15 2014 +0100
@@ -113,3 +113,4 @@
 compiler.warn.file.from.future                          # warning for future modification times on files
 compiler.err.cant.inherit.from.anon                     # error for subclass of anonymous class
 compiler.misc.bad.class.file                            # class file is malformed
+compiler.misc.bad.const.pool.entry                      # constant pool entry has wrong type