diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/verifier/ParserVerifier.java b/src/java.base/share/classes/jdk/internal/classfile/impl/verifier/ParserVerifier.java index b7ddaace116..f860fb4a1bd 100644 --- a/src/java.base/share/classes/jdk/internal/classfile/impl/verifier/ParserVerifier.java +++ b/src/java.base/share/classes/jdk/internal/classfile/impl/verifier/ParserVerifier.java @@ -34,10 +34,9 @@ import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; -import java.util.function.Consumer; +import java.util.stream.Collectors; import java.util.function.Function; import java.util.function.ToIntFunction; -import java.util.stream.Collectors; import jdk.internal.classfile.impl.BoundAttribute; import jdk.internal.classfile.impl.Util; @@ -65,50 +64,79 @@ public record ParserVerifier(ClassModel classModel) { private void verifyConstantPool(List errors) { for (var cpe : classModel.constantPool()) { - Consumer 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)))); + 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(); + case FieldRefEntry fre -> { + try { + fre.owner().asSymbol(); + } catch (VerifyError|Exception e) { + errors.add(cpeVerifyError(cpe, e)); + } + try { + fre.typeSymbol(); + } catch (VerifyError|Exception e) { + errors.add(cpeVerifyError(cpe, e)); + } + verifyFieldName(fre.name().stringValue()); + } + case InterfaceMethodRefEntry imre -> { + try { + imre.owner().asSymbol(); + } catch (VerifyError|Exception e) { + errors.add(cpeVerifyError(cpe, e)); + } + try { + imre.typeSymbol(); + } catch (VerifyError|Exception e) { + errors.add(cpeVerifyError(cpe, e)); + } + verifyMethodName(imre.name().stringValue()); + } + case MethodRefEntry mre -> { + try { + mre.owner().asSymbol(); + } catch (VerifyError|Exception e) { + errors.add(cpeVerifyError(cpe, e)); + } + try { + mre.typeSymbol(); + } catch (VerifyError|Exception e) { + errors.add(cpeVerifyError(cpe, e)); + } + verifyMethodName(mre.name().stringValue()); + } + case ModuleEntry me -> me.asSymbol(); + case NameAndTypeEntry nate -> { + try { + nate.name().stringValue(); + } catch (VerifyError|Exception e) { + errors.add(cpeVerifyError(cpe, e)); + } + nate.type().stringValue(); + } + case PackageEntry pe -> pe.asSymbol(); } - }; - 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 -> { - check.accept(fre.owner()::asSymbol); - check.accept(fre::typeSymbol); - yield () -> verifyFieldName(fre.name().stringValue()); - } - case InterfaceMethodRefEntry imre -> { - check.accept(imre.owner()::asSymbol); - check.accept(imre::typeSymbol); - yield () -> verifyMethodName(imre.name().stringValue()); - } - case MethodRefEntry mre -> { - check.accept(mre.owner()::asSymbol); - check.accept(mre::typeSymbol); - yield () -> verifyMethodName(mre.name().stringValue()); - } - case ModuleEntry me -> me::asSymbol; - case NameAndTypeEntry nate -> { - check.accept(nate.name()::stringValue); - yield () -> nate.type().stringValue(); - } - case PackageEntry pe -> pe::asSymbol; - }); + } catch (VerifyError|Exception e) { + errors.add(cpeVerifyError(cpe, e)); + } } } + private VerifyError cpeVerifyError(final PoolEntry cpe, final Throwable e) { + return new VerifyError("%s at constant pool index %d in %s".formatted(e.getMessage(), cpe.index(), toString(classModel))); + } + private void verifyFieldName(String name) { if (name.length() == 0 || name.chars().anyMatch(ch -> switch(ch) { case '.', ';', '[', '/' -> true;