mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 07:14:30 +02:00
8333812: ClassFile.verify() can throw exceptions instead of returning VerifyErrors
Reviewed-by: liach
This commit is contained in:
parent
6e9fcc2d80
commit
c25c4896ad
4 changed files with 44 additions and 7 deletions
|
@ -286,7 +286,11 @@ public abstract sealed class BoundAttribute<T extends Attribute<T>>
|
||||||
|
|
||||||
public BoundLocalVariableTableAttribute(AttributedElement enclosing, ClassReader cf, AttributeMapper<LocalVariableTableAttribute> mapper, int pos) {
|
public BoundLocalVariableTableAttribute(AttributedElement enclosing, ClassReader cf, AttributeMapper<LocalVariableTableAttribute> mapper, int pos) {
|
||||||
super(cf, mapper, pos);
|
super(cf, mapper, pos);
|
||||||
codeAttribute = (CodeImpl) enclosing;
|
if (enclosing instanceof CodeImpl ci) {
|
||||||
|
this.codeAttribute = ci;
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Invalid LocalVariableTable attribute location");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -313,7 +317,11 @@ public abstract sealed class BoundAttribute<T extends Attribute<T>>
|
||||||
|
|
||||||
public BoundLocalVariableTypeTableAttribute(AttributedElement enclosing, ClassReader cf, AttributeMapper<LocalVariableTypeTableAttribute> mapper, int pos) {
|
public BoundLocalVariableTypeTableAttribute(AttributedElement enclosing, ClassReader cf, AttributeMapper<LocalVariableTypeTableAttribute> mapper, int pos) {
|
||||||
super(cf, mapper, pos);
|
super(cf, mapper, pos);
|
||||||
this.codeAttribute = (CodeImpl) enclosing;
|
if (enclosing instanceof CodeImpl ci) {
|
||||||
|
this.codeAttribute = ci;
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Invalid LocalVariableTypeTable attribute location");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -132,7 +132,11 @@ public record ClassFileImpl(StackMapsOption stackMapsOption,
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<VerifyError> verify(ClassModel model) {
|
public List<VerifyError> verify(ClassModel model) {
|
||||||
|
try {
|
||||||
return VerifierImpl.verify(model, classHierarchyResolverOption().classHierarchyResolver(), null);
|
return VerifierImpl.verify(model, classHierarchyResolverOption().classHierarchyResolver(), null);
|
||||||
|
} catch (IllegalArgumentException verifierInitializationError) {
|
||||||
|
return List.of(new VerifyError(verifierInitializationError.getMessage()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -114,9 +114,10 @@ public final class VerifierImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<VerifyError> verify(ClassModel classModel, ClassHierarchyResolver classHierarchyResolver, Consumer<String> logger) {
|
public static List<VerifyError> verify(ClassModel classModel, ClassHierarchyResolver classHierarchyResolver, Consumer<String> logger) {
|
||||||
var klass = new VerificationWrapper(classModel);
|
String clsName = classModel.thisClass().asInternalName();
|
||||||
log_info(logger, "Start class verification for: %s", klass.thisClassName());
|
log_info(logger, "Start class verification for: %s", clsName);
|
||||||
try {
|
try {
|
||||||
|
var klass = new VerificationWrapper(classModel);
|
||||||
var errors = new ArrayList<VerifyError>();
|
var errors = new ArrayList<VerifyError>();
|
||||||
errors.addAll(new ParserVerifier(classModel).verify());
|
errors.addAll(new ParserVerifier(classModel).verify());
|
||||||
if (is_eligible_for_verification(klass)) {
|
if (is_eligible_for_verification(klass)) {
|
||||||
|
@ -134,7 +135,7 @@ public final class VerifierImpl {
|
||||||
}
|
}
|
||||||
return errors;
|
return errors;
|
||||||
} finally {
|
} finally {
|
||||||
log_info(logger, "End class verification for: %s", klass.thisClassName());
|
log_info(logger, "End class verification for: %s", clsName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
/*
|
/*
|
||||||
* @test
|
* @test
|
||||||
* @summary Testing ClassFile Verifier.
|
* @summary Testing ClassFile Verifier.
|
||||||
|
* @bug 8333812
|
||||||
* @enablePreview
|
* @enablePreview
|
||||||
* @run junit VerifierSelfTest
|
* @run junit VerifierSelfTest
|
||||||
*/
|
*/
|
||||||
|
@ -46,8 +47,10 @@ import java.lang.classfile.*;
|
||||||
import java.lang.classfile.attribute.*;
|
import java.lang.classfile.attribute.*;
|
||||||
import java.lang.classfile.components.ClassPrinter;
|
import java.lang.classfile.components.ClassPrinter;
|
||||||
import java.lang.constant.ModuleDesc;
|
import java.lang.constant.ModuleDesc;
|
||||||
|
import jdk.internal.classfile.impl.DirectClassBuilder;
|
||||||
|
import jdk.internal.classfile.impl.UnboundAttribute;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import static org.junit.jupiter.api.Assertions.fail;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
class VerifierSelfTest {
|
class VerifierSelfTest {
|
||||||
|
|
||||||
|
@ -94,6 +97,27 @@ class VerifierSelfTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testInvalidAttrLocation() {
|
||||||
|
var cc = ClassFile.of();
|
||||||
|
var bytes = cc.build(ClassDesc.of("InvalidAttrLocationClass"), cb ->
|
||||||
|
((DirectClassBuilder)cb).writeAttribute(new UnboundAttribute.AdHocAttribute<LocalVariableTableAttribute>(Attributes.localVariableTable()) {
|
||||||
|
@Override
|
||||||
|
public void writeBody(BufWriter b) {
|
||||||
|
b.writeU2(0);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
assertTrue(cc.verify(bytes).stream().anyMatch(e -> e.getMessage().contains("Invalid LocalVariableTable attribute location")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testInvalidClassNameEntry() {
|
||||||
|
var cc = ClassFile.of();
|
||||||
|
var bytes = cc.parse(new byte[]{(byte)0xCA, (byte)0xFE, (byte)0xBA, (byte)0xBE,
|
||||||
|
0, 0, 0, 0, 0, 2, ClassFile.TAG_INTEGER, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0});
|
||||||
|
assertTrue(cc.verify(bytes).stream().anyMatch(e -> e.getMessage().contains("expected ClassEntry")));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testParserVerification() {
|
void testParserVerification() {
|
||||||
var cc = ClassFile.of();
|
var cc = ClassFile.of();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue