When javac reads a MethodParameters attribute with fewer entries than there are method parameters, it does not do a bounds check before reading from the array parameterNameIndicesMp here [1]. Note that there is a corresponding bounds check for parameterNameIndicesLvt below that code.
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)