# HG changeset patch # User pgovereau # Date 1398192735 -3600 # Node ID d8a1180faaa91d8be7f618d3209734b0a2f0e784 # Parent 76e7b6bbbd855208529c5bd50b359c6aed822756 8038023: Compiler crash ClassCastException Summary: Add additional checks on results of ClassReader.readPool Reviewed-by: vromero diff -r 76e7b6bbbd85 -r d8a1180faaa9 langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java --- 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); diff -r 76e7b6bbbd85 -r d8a1180faaa9 langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties --- 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\ diff -r 76e7b6bbbd85 -r d8a1180faaa9 langtools/test/tools/javac/diags/examples.not-yet.txt --- 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