RFR: 8268894: ArrayIndexOutOfBoundsException in jdk compiler: at jdk.compiler/com.sun.tools.javac.jvm.ClassWriter.writePosition(ClassWriter.java:671)

Manuel Ryan github.com+223869+mryan43 at openjdk.java.net
Wed Aug 25 13:52:23 UTC 2021


On Sun, 11 Jul 2021 09:36:53 GMT, Guoxiong Li <gli at openjdk.org> wrote:

> Hi all,
> 
> The method `TypeAnnotationPosition.updatePosOffset` sets the `lvarOffset` unnecessarily. After invoking `TypeAnnotationPosition.updatePosOffset`, the lengths of (`lvarOffset`, `lvarLength`, `lvarIndex`) are respectively (1, 0, 0). Then `Code.fillLocalVarPosition` fills the `lvarOffset`, `lvarLength`, `lvarIndex` which make their lengths become (N, N-1, N-1). At last, the method `ClassWrite.writePosition` uses these three arrays whose lengths are not the same so that the `ArrayIndexOutOfBoundsException` occurs.
> 
> The `lvarOffset` should be always changed along with `lvarLength` and `lvarIndex` so that their lengths can be the same.
> 
> This patch removes the unnecessary `lvarOffset = new int[]{to};` of the method  `TypeAnnotationPosition.updatePosOffset` and add a corresponding test.
> 
> ---
> Steps to reproduce the issue:
> 
> 1. Construct a annotation processor which set the `pos` of the method sub-tree nodes to the same position. Please see the file `TypeAnnotationPositionProcessor.java` for more details.
> 2. Compile the code which has the corresponding method with the annotated local variable by using the annotation processor generated at the step 1. Please see the file `TypeAnnotationPositionTest.java` for more details.
> 3. Then the crash occurs.
> 
> Actually, this bug may never occur if the users use the compiler friendly. Because the method `TypeAnnotationPosition.updatePosOffset`, which we mentioned at the beginning, may never be invoked at the situation that the different trees has different and right position.
> 
> The lib `lombok` constructs some new tree nodes by using the internal method of the compiler. But it doesn't set the `pos` correctly and uses the same fake position. The unfriendly code of the `lombok` is in the method [JavacHandlerUtil.setGeneratedBy](https://github.com/projectlombok/lombok/blob/master/src/core/lombok/javac/handlers/JavacHandlerUtil.java#L167). At much time, the fake same position works well, but this time, it crashes the compiler.
> 
> ---
> A brief history:
> 
> According to the git's records, I found the code `ta.position.lvarOffset = new int[] { code.cp };` was firstly added at [8006775: JSR 308: Compiler changes in JDK8](http://hg.openjdk.java.net/jdk8/jdk8/langtools/rev/71f35e4b93a5#l52.35) .
> 
> Then, [8013852: update reference impl for type-annotations](http://hg.openjdk.java.net/jdk8/jdk8/langtools/rev/ddb4a2bfcd82#l8.52) moved the code to `TypeAnnotationPosition.updatePosOffset`.
> 
> The bug didn't occur at that time, because the old [Code.fillLocalVarPosition](http://hg.openjdk.java.net/jdk8/jdk8/langtools/rev/71f35e4b93a5#l51.21) always created a new array instead of using the old array.
> 
> But later, [8231826: Implement javac changes for pattern matching for instanceof](https://hg.openjdk.java.net/jdk/jdk/rev/7799a51dbe30#l24.27) revised the method `Code.fillLocalVarPosition` to reuse the old array so that the bug occurs.
> 
> Concluded, this is an issue introduced at JDK8 when implementing the type annotation. But it was hidden by other code at the past. 
> 
> ---
> 
> Thanks for taking the time to review.
> 
> Best Regards,
> -- Guoxiong

This is still preventing me to upgrade from 11 to 15. Please don't let this issue be automatically deleted because of inactivity.

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

PR: https://git.openjdk.java.net/jdk/pull/4749


More information about the compiler-dev mailing list