RFR: 8302514: Misleading error generated when empty class file encountered [v2]

Archie L. Cobbs duke at openjdk.org
Wed Feb 15 16:23:54 UTC 2023


> When javac encounters an empty class file, you get the following strange error referring to `java.lang.AutoCloseable`:
> 
> Test.java:3: error: cannot access Empty
>         new Empty();
>             ^
>   bad class file: ./Empty.class
>     class file contains wrong class: java.lang.AutoCloseable
>     Please remove or make sure it appears in the correct subdirectory of the classpath.
> 1 error
> 
> This is a side effect of javac blindly reading past the end of the data in a data buffer. Further investigation revealed three distinct bugs in this area of the code:
> 
> 1. There are several unchecked corner cases in `ByteBuffer` and `ArrayUtils` that could potentially lead to `ArrayIndexOutOfBoundsException`s and/or infinite loops. Instead we should "fail fast" on any attempt to read or allocate data out of bounds.
> 1. The method `ByteBuffer.appendStream()` assumes that the result from `InputStream.available()` is always accurate, but this is not guaranteed. As a result, class files could (in theory) be read incorrectly by the compiler, especially when they come from non-standard sources.
> 1. There is no systematic protection against truncated class files. Instead, depending on where exactly it is truncated, a truncated class file generates one of several possible different errors:
>    * `index 25926 is not within pool size 13`
>    * `bad constant pool tag: 0 at 28317`
>    * `unexpected constant pool tag: 10 at 11`
>    * `class file is invalid for class Empty`
>    * `class file contains wrong class: java.lang.AutoCloseable`
> 
> This patch fixes issues 1 and 2, and addresses 3 by having `ByteBuffer` throw a new unchecked `UnderflowException` if ever data is read past the end of the buffer. Then `PoolReader`, `ClassReader`, and `ModuleNameReader` are updated to catch this exception and convert it into a bad class file error. As a result, truncated class files generate a consistent `class file truncated at offset X` error regardless of where they are truncated.

Archie L. Cobbs has updated the pull request incrementally with one additional commit since the last revision:

  Fix another ArrayUtils corner case created by previous fix.

-------------

Changes:
  - all: https://git.openjdk.org/jdk/pull/12574/files
  - new: https://git.openjdk.org/jdk/pull/12574/files/0db96e30..22625db5

Webrevs:
 - full: https://webrevs.openjdk.org/?repo=jdk&pr=12574&range=01
 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=12574&range=00-01

  Stats: 3 lines in 1 file changed: 0 ins; 2 del; 1 mod
  Patch: https://git.openjdk.org/jdk/pull/12574.diff
  Fetch: git fetch https://git.openjdk.org/jdk pull/12574/head:pull/12574

PR: https://git.openjdk.org/jdk/pull/12574


More information about the compiler-dev mailing list