-
Bug
-
Resolution: Fixed
-
P3
-
11.0.23, 17.0.11, 21.0.2, 22
-
b03
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8323204 | 21.0.3-oracle | Jan Lahoda | P3 | Resolved | Fixed | b02 |
JDK-8322642 | 21.0.3 | Liam Miller-Cushon | P3 | Resolved | Fixed | b01 |
The ArrayIndexOutOfBounds exception is handled by ClassReader [2] and results in a bad.class.file error.
I noticed this while debugging a crash for a class that had ended up in a bad state, and I think the root cause is that the class is getting 'half completed' before MethodParameter attribute handling crashes, and then the compilation handles the exception and continues with the class file in a bad state.
[1] https://github.com/openjdk/jdk/blob/cf948548c390c42ca63525d41a9d63ff31349c3a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java#L2805-L2807
[2] https://github.com/openjdk/jdk/blob/cf948548c390c42ca63525d41a9d63ff31349c3a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java#L3108
---
I found the following crash while try to produce a repro, which is slightly different than the original crash I found:
```
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;
import java.util.Set;
@SupportedAnnotationTypes("*")
public class P extends AbstractProcessor {
@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latestSupported();
}
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
processingEnv
.getMessager()
.printMessage(
Diagnostic.Kind.NOTE,
processingEnv
.getElementUtils()
.getTypeElement("T.I")
.getEnclosedElements()
.toString());
return false;
}
}
```
```
import java.nio.file.Files;
import java.nio.file.Paths;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
public class TDump implements Opcodes {
public static void main(String[] args) throws Exception {
Files.write(Paths.get("T.class"), dump());
}
public static byte[] dump() throws Exception {
ClassWriter classWriter = new ClassWriter(0);
MethodVisitor methodVisitor;
classWriter.visit(V19, ACC_SUPER, "T", null, "java/lang/Object", null);
classWriter.visitSource("T.java", null);
classWriter.visitNestMember("T$I");
classWriter.visitInnerClass("T$I", "T", "I", 0);
{
methodVisitor = classWriter.visitMethod(0, "<init>", "()V", null, null);
methodVisitor.visitCode();
Label label0 = new Label();
methodVisitor.visitLabel(label0);
methodVisitor.visitLineNumber(1, label0);
methodVisitor.visitVarInsn(ALOAD, 0);
methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
methodVisitor.visitInsn(RETURN);
methodVisitor.visitMaxs(1, 1);
methodVisitor.visitEnd();
}
{
methodVisitor = classWriter.visitMethod(ACC_PUBLIC | ACC_STATIC, "f", "(II)V", null, null);
methodVisitor.visitParameter("x", 0);
methodVisitor.visitCode();
Label label0 = new Label();
methodVisitor.visitLabel(label0);
methodVisitor.visitLineNumber(3, label0);
methodVisitor.visitInsn(RETURN);
methodVisitor.visitMaxs(0, 2);
methodVisitor.visitEnd();
}
classWriter.visitEnd();
return classWriter.toByteArray();
}
}
```
```
class T {
public static void f(int x, int y) {
}
class I {}
}
```
javac -cp asm-9.5.jar:asm-util-9.5.jar TDump.java T.java P.java
java -cp asm-9.5.jar:asm-util-9.5.jar:. TDump
javac -parameters -processor P T.I
...
An exception has occurred in the compiler (22-internal). Please file a bug against the Java compiler via the Java bug reporting page (https://bugreport.java.com) after checking the Bug Database (https://bugs.java.com) for duplicates. Include your program, the following diagnostic, and the parameters passed to the Java compiler in your report. Thank you.
java.lang.ClassCastException: class com.sun.tools.javac.comp.Resolve$BadClassFileError cannot be cast to class com.sun.tools.javac.code.Symbol$ClassSymbol (com.sun.tools.javac.comp.Resolve$BadClassFileError and com.sun.tools.javac.code.Symbol$ClassSymbol are in module jdk.compiler of loader 'app')
at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1255)
at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:946)
at jdk.compiler/com.sun.tools.javac.main.Main.compile(Main.java:319)
at jdk.compiler/com.sun.tools.javac.main.Main.compile(Main.java:178)
at jdk.compiler/com.sun.tools.javac.Main.compile(Main.java:66)
at jdk.compiler/com.sun.tools.javac.Main.main(Main.java:52)
- backported by
-
JDK-8322642 Missing array bounds check in ClassReader.parameter
- Resolved
-
JDK-8323204 Missing array bounds check in ClassReader.parameter
- Resolved
- is cloned by
-
JDK-8346469 [REDO BACKPORT] Missing array bounds check in ClassReader.parameter
- Closed
- relates to
-
JDK-8322175 test/langtools/tools/javac/classreader/BadMethodParameter.java doesn't compile
- Resolved
-
JDK-8292275 javac does not emit SYNTHETIC and MANDATED flags for parameters by default
- Resolved
- links to
-
Commit openjdk/jdk21u-dev/aaee2d75
-
Commit openjdk/jdk/20de541b
-
Review openjdk/jdk21u-dev/74
-
Review openjdk/jdk22u/4
-
Review openjdk/jdk/17097