changeset 2398:3a2ebbad5911

8038023: Compiler crash ClassCastException Summary: Add additional checks on results of ClassReader.readPool Reviewed-by: vromero
author pgovereau
date Wed, 30 Apr 2014 23:26:43 +0100
parents 9087c3c6920b
children 12f99d1f23d9
files src/share/classes/com/sun/tools/javac/jvm/ClassReader.java src/share/classes/com/sun/tools/javac/resources/compiler.properties test/tools/javac/diags/examples.not-yet.txt
diffstat 3 files changed, 32 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Wed Apr 23 11:28:09 2014 +0200
+++ b/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Wed Apr 30 23:26:43 2014 +0100
@@ -512,14 +512,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;
         }
@@ -588,13 +588,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;
     }
 
 /************************************************************************
@@ -1245,7 +1266,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/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Wed Apr 23 11:28:09 2014 +0200
+++ b/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Wed Apr 30 23:26:43 2014 +0100
@@ -1705,6 +1705,11 @@
     cannot access {0}\n\
     {1}
 
+# 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/test/tools/javac/diags/examples.not-yet.txt	Wed Apr 23 11:28:09 2014 +0200
+++ b/test/tools/javac/diags/examples.not-yet.txt	Wed Apr 30 23:26:43 2014 +0100
@@ -111,3 +111,4 @@
 compiler.warn.unknown.enum.constant.reason              # in bad class file
 compiler.warn.override.equals.but.not.hashcode          # when a class overrides equals but not hashCode method from Object
 compiler.err.cant.inherit.from.anon                     # error for subclass of anonymous class
+compiler.misc.bad.const.pool.entry                      # constant pool entry has wrong type