Skip to content

Commit

Permalink
work in progress
Browse files Browse the repository at this point in the history
  • Loading branch information
asotona committed Nov 28, 2023
1 parent 439eae3 commit 215c44c
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 59 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,13 @@
package jdk.internal.classfile.impl.verifier;

import java.lang.constant.ClassDesc;
import static java.lang.constant.ConstantDescs.CLASS_INIT_NAME;
import static java.lang.constant.ConstantDescs.INIT_NAME;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import jdk.internal.classfile.Attribute;
import jdk.internal.classfile.AttributedElement;
Expand All @@ -54,56 +58,68 @@ List<VerifyError> verify() {
}

private void verifyConstantPool(List<VerifyError> errors) {
for (var cpe : classModel.constantPool()) try {
switch (cpe) {
case DoubleEntry de ->
de.doubleValue();
case FloatEntry fe ->
fe.floatValue();
case IntegerEntry ie ->
ie.intValue();
case LongEntry le ->
le.longValue();
case Utf8Entry ue ->
ue.stringValue();
case ConstantDynamicEntry cde ->
cde.asSymbol();
case InvokeDynamicEntry ide ->
ide.asSymbol();
case ClassEntry ce ->
ce.asSymbol();
case StringEntry se ->
se.stringValue();
case MethodHandleEntry mhe ->
mhe.asSymbol();
case MethodTypeEntry mte ->
mte.asSymbol();
for (var cpe : classModel.constantPool()) {
Consumer<Runnable> check = c -> {
try {
c.run();
} catch (VerifyError|Exception e) {
errors.add(new VerifyError("%s at constant pool index %d in %s".formatted(e.getMessage(), cpe.index(), toString(classModel))));
}
};
check.accept(switch (cpe) {
case DoubleEntry de -> de::doubleValue;
case FloatEntry fe -> fe::floatValue;
case IntegerEntry ie -> ie::intValue;
case LongEntry le -> le::longValue;
case Utf8Entry ue -> ue::stringValue;
case ConstantDynamicEntry cde -> cde::asSymbol;
case InvokeDynamicEntry ide -> ide::asSymbol;
case ClassEntry ce -> ce::asSymbol;
case StringEntry se -> se::stringValue;
case MethodHandleEntry mhe -> mhe::asSymbol;
case MethodTypeEntry mte -> mte::asSymbol;
case FieldRefEntry fre -> {
fre.owner().asSymbol();
fre.name().stringValue();
fre.typeSymbol();
check.accept(fre.owner()::asSymbol);
check.accept(fre::typeSymbol);
yield () -> verifyFieldName(fre.name().stringValue());
}
case InterfaceMethodRefEntry imre -> {
imre.owner().asSymbol();
imre.name().stringValue();
imre.typeSymbol();
check.accept(imre.owner()::asSymbol);
check.accept(imre::typeSymbol);
yield () -> verifyMethodName(imre.name().stringValue());
}
case MethodRefEntry mre -> {
mre.owner().asSymbol();
mre.name().stringValue();
mre.typeSymbol();
check.accept(mre.owner()::asSymbol);
check.accept(mre::typeSymbol);
yield () -> verifyMethodName(mre.name().stringValue());
}
case ModuleEntry me ->
me.asSymbol();
case ModuleEntry me -> me::asSymbol;
case NameAndTypeEntry nate -> {
nate.name().stringValue();
nate.type().stringValue();
check.accept(nate.name()::stringValue);
yield () -> nate.type().stringValue();
}
case PackageEntry pe ->
pe.asSymbol();
}
} catch (IllegalArgumentException iae) {
errors.add(new VerifyError("%s at constant pool index %d in %s".formatted(iae.getMessage(), cpe.index(), toString(classModel))));
case PackageEntry pe -> pe::asSymbol;
});
}
}

private void verifyFieldName(String name) {
if (name.length() == 0 || name.chars().anyMatch(ch -> switch(ch) {
case '.', ';', '[', '/' -> true;
default -> false;
})) {
throw new VerifyError("Illegal field name %s in %s".formatted(name, toString(classModel)));
}
}

private void verifyMethodName(String name) {
if (!name.equals(INIT_NAME)
&& !name.equals(CLASS_INIT_NAME)
&& (name.length() == 0 || name.chars().anyMatch(ch -> switch(ch) {
case '.', ';', '[', '/', '<', '>' -> true;
default -> false;
}))) {
throw new VerifyError("Illegal method name %s in %s".formatted(name, toString(classModel)));
}
}

Expand Down
34 changes: 17 additions & 17 deletions test/jdk/jdk/classfile/VerifierSelfTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -103,40 +103,40 @@ void testFailedDump() throws IOException {
void testConstantPoolVerification() {
var cc = Classfile.of();
var cd_test = ClassDesc.of("ConstantPoolTestClass");
var indexes = new int[12];
var indexes = new int[9];
var clm = cc.parse(cc.build(cd_test, clb -> {
var cp = clb.constantPool();
var ce_valid = cp.classEntry(cd_test);
var ce_invalid = cp.classEntry(cp.utf8Entry("invalid.class.name"));
indexes[0] = ce_invalid.index();
var nate_field = cp.nameAndTypeEntry("field", CD_int);
var nate_method = cp.nameAndTypeEntry(" method", MTD_void);
var nate_invalid_field = cp.nameAndTypeEntry("field;", CD_int);
var nate_invalid_method = cp.nameAndTypeEntry("method;", MTD_void);
var bsme = cp.bsmEntry(BSM_INVOKE, List.of());
indexes[1] = cp.methodTypeEntry(cp.utf8Entry("invalid method type")).index();
indexes[2] = cp.constantDynamicEntry(bsme, nate_method).index();
indexes[3] = cp.invokeDynamicEntry(bsme, nate_field).index();
indexes[4] = cp.fieldRefEntry(ce_valid, nate_method).index();
indexes[5] = cp.fieldRefEntry(ce_invalid, nate_field).index();
indexes[6] = cp.methodRefEntry(ce_valid, nate_field).index();
indexes[7] = cp.methodRefEntry(ce_invalid, nate_method).index();
indexes[8] = cp.interfaceMethodRefEntry(ce_valid, nate_field).index();
indexes[9] = cp.interfaceMethodRefEntry(ce_invalid, nate_method).index();
indexes[10] = cp.methodHandleEntry(MethodHandleInfo.REF_getField, cp.methodRefEntry(cd_test, "method", MTD_void)).index();
indexes[11] = cp.methodHandleEntry(MethodHandleInfo.REF_invokeVirtual, cp.fieldRefEntry(cd_test, "field", CD_int)).index();
indexes[2] = cp.constantDynamicEntry(bsme, nate_invalid_method).index();
indexes[3] = cp.invokeDynamicEntry(bsme, nate_invalid_field).index();
indexes[4] = cp.fieldRefEntry(ce_invalid, nate_invalid_method).index();
indexes[5] = cp.methodRefEntry(ce_invalid, nate_invalid_field).index();
indexes[6] = cp.interfaceMethodRefEntry(ce_invalid, nate_invalid_field).index();
indexes[7] = cp.methodHandleEntry(MethodHandleInfo.REF_getField, cp.methodRefEntry(cd_test, "method", MTD_void)).index();
indexes[8] = cp.methodHandleEntry(MethodHandleInfo.REF_invokeVirtual, cp.fieldRefEntry(cd_test, "field", CD_int)).index();
}));
assertVerify(clm, STR."""
Invalid class name: invalid.class.name at constant pool index \{ indexes[0] } in class ConstantPoolTestClass
Bad method descriptor: invalid method type at constant pool index \{ indexes[1] } in class ConstantPoolTestClass
not a valid reference type descriptor: ()V at constant pool index \{ indexes[2] } in class ConstantPoolTestClass
Bad method descriptor: I at constant pool index \{ indexes[3] } in class ConstantPoolTestClass
not a valid reference type descriptor: ()V at constant pool index \{ indexes[4] } in class ConstantPoolTestClass
Invalid class name: invalid.class.name at constant pool index \{ indexes[4] } in class ConstantPoolTestClass
Illegal field name method; in class ConstantPoolTestClass at constant pool index \{ indexes[4] } in class ConstantPoolTestClass
Bad method descriptor: I at constant pool index \{ indexes[5] } in class ConstantPoolTestClass
Invalid class name: invalid.class.name at constant pool index \{ indexes[5] } in class ConstantPoolTestClass
Illegal method name field; in class ConstantPoolTestClass at constant pool index \{ indexes[5] } in class ConstantPoolTestClass
Bad method descriptor: I at constant pool index \{ indexes[6] } in class ConstantPoolTestClass
Invalid class name: invalid.class.name at constant pool index \{ indexes[7] } in class ConstantPoolTestClass
Invalid class name: invalid.class.name at constant pool index \{ indexes[6] } in class ConstantPoolTestClass
Illegal method name field; in class ConstantPoolTestClass at constant pool index \{ indexes[6] } in class ConstantPoolTestClass
not a valid reference type descriptor: ()V at constant pool index \{ indexes[7] } in class ConstantPoolTestClass
Bad method descriptor: I at constant pool index \{ indexes[8] } in class ConstantPoolTestClass
Invalid class name: invalid.class.name at constant pool index \{ indexes[9] } in class ConstantPoolTestClass
not a valid reference type descriptor: ()V at constant pool index \{ indexes[10] } in class ConstantPoolTestClass
Bad method descriptor: I at constant pool index \{ indexes[11] } in class ConstantPoolTestClass
""");
}

Expand Down

0 comments on commit 215c44c

Please sign in to comment.