Skip to content

Commit

Permalink
error when reading class file with unknown newer jdk version
Browse files Browse the repository at this point in the history
  • Loading branch information
bishabosha committed Nov 3, 2023
1 parent dc012c3 commit f430e44
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ object ClassfileConstants {
inline val JAVA_MINOR_VERSION = 3

inline val JAVA8_MAJOR_VERSION = 52
inline val JAVA_LATEST_MAJOR_VERSION = 65

/** (see http://java.sun.com/docs/books/jvms/second_edition/jvms-clarify.html)
*
Expand Down
31 changes: 17 additions & 14 deletions compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,22 @@ object ClassfileParser {
}
}

private[classfile] def parseHeader(classfile: AbstractFile)(using in: DataReader): Unit = {
val magic = in.nextInt
if (magic != JAVA_MAGIC)
throw new IOException(s"class file '${classfile}' has wrong magic number 0x${toHexString(magic)}, should be 0x${toHexString(JAVA_MAGIC)}")
val minorVersion = in.nextChar.toInt
val majorVersion = in.nextChar.toInt
if ((majorVersion < JAVA_MAJOR_VERSION) ||
((majorVersion == JAVA_MAJOR_VERSION) &&
(minorVersion < JAVA_MINOR_VERSION)))
throw new IOException(
s"class file '${classfile}' has unknown version $majorVersion.$minorVersion, should be at least $JAVA_MAJOR_VERSION.$JAVA_MINOR_VERSION")
if majorVersion > JAVA_LATEST_MAJOR_VERSION then
throw new IOException(
s"class file '${classfile}' has unknown version $majorVersion.$minorVersion, and was compiled by a newer JDK than supported by this Scala version, please update to a newer Scala version.")
}

abstract class AbstractConstantPool(using in: DataReader) {
protected val len = in.nextChar
protected val starts = new Array[Int](len)
Expand Down Expand Up @@ -259,7 +275,7 @@ class ClassfileParser(
def run()(using Context): Option[Embedded] = try ctx.base.reusableDataReader.withInstance { reader =>
implicit val reader2 = reader.reset(classfile)
report.debuglog("[class] >> " + classRoot.fullName)
parseHeader()
parseHeader(classfile)
this.pool = new ConstantPool
val res = parseClass()
this.pool = null
Expand All @@ -273,19 +289,6 @@ class ClassfileParser(
|${Option(e.getMessage).getOrElse("")}""")
}

private def parseHeader()(using in: DataReader): Unit = {
val magic = in.nextInt
if (magic != JAVA_MAGIC)
throw new IOException(s"class file '${classfile}' has wrong magic number 0x${toHexString(magic)}, should be 0x${toHexString(JAVA_MAGIC)}")
val minorVersion = in.nextChar.toInt
val majorVersion = in.nextChar.toInt
if ((majorVersion < JAVA_MAJOR_VERSION) ||
((majorVersion == JAVA_MAJOR_VERSION) &&
(minorVersion < JAVA_MINOR_VERSION)))
throw new IOException(
s"class file '${classfile}' has unknown version $majorVersion.$minorVersion, should be at least $JAVA_MAJOR_VERSION.$JAVA_MINOR_VERSION")
}

/** Return the class symbol of the given name. */
def classNameToSymbol(name: Name)(using Context): Symbol =
val nameStr = name.toString
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class ClassfileTastyUUIDParser(classfile: AbstractFile)(ictx: Context) {

def checkTastyUUID(tastyUUID: UUID)(using Context): Unit = try ctx.base.reusableDataReader.withInstance { reader =>
implicit val reader2 = reader.reset(classfile)
parseHeader()
ClassfileParser.parseHeader(classfile)
this.pool = new ConstantPool
checkTastyAttr(tastyUUID)
this.pool = null
Expand All @@ -39,19 +39,6 @@ class ClassfileTastyUUIDParser(classfile: AbstractFile)(ictx: Context) {
|${Option(e.getMessage).getOrElse("")}""")
}

private def parseHeader()(using in: DataReader): Unit = {
val magic = in.nextInt
if (magic != JAVA_MAGIC)
throw new IOException(s"class file '${classfile}' has wrong magic number 0x${toHexString(magic)}, should be 0x${toHexString(JAVA_MAGIC)}")
val minorVersion = in.nextChar.toInt
val majorVersion = in.nextChar.toInt
if ((majorVersion < JAVA_MAJOR_VERSION) ||
((majorVersion == JAVA_MAJOR_VERSION) &&
(minorVersion < JAVA_MINOR_VERSION)))
throw new IOException(
s"class file '${classfile}' has unknown version $majorVersion.$minorVersion, should be at least $JAVA_MAJOR_VERSION.$JAVA_MINOR_VERSION")
}

private def checkTastyAttr(tastyUUID: UUID)(using ctx: Context, in: DataReader): Unit = {
in.nextChar // jflags
in.nextChar // nameIdx
Expand Down

0 comments on commit f430e44

Please sign in to comment.