8361908: Mix and match of dead and valid exception handler leads to malformed class file

Reviewed-by: asotona
This commit is contained in:
Chen Liang 2025-07-11 22:52:26 +00:00
parent 3f59eae3d0
commit 189017f750
2 changed files with 21 additions and 2 deletions

View File

@ -206,7 +206,6 @@ public final class DirectCodeBuilder
} else {
buf.writeU2U2U2(startPc, endPc, handlerPc);
buf.writeIndexOrZero(h.catchTypeEntry());
handlersSize++;
}
}
if (handlersSize < handlers.size())

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -23,15 +23,18 @@
/*
* @test
* @bug 8361908
* @summary Testing filtering of dead labels.
* @run junit FilterDeadLabelsTest
*/
import java.lang.classfile.ClassFile;
import java.lang.classfile.instruction.ExceptionCatch;
import java.lang.constant.ClassDesc;
import java.lang.constant.ConstantDescs;
import java.lang.constant.MethodTypeDesc;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
import java.lang.classfile.Attributes;
import java.lang.classfile.CodeBuilder;
@ -41,6 +44,8 @@ import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import static java.lang.constant.ConstantDescs.*;
class FilterDeadLabelsTest {
static List<Consumer<CodeBuilder>> deadLabelFragments() {
@ -71,6 +76,21 @@ class FilterDeadLabelsTest {
code.findAttribute(Attributes.characterRangeTable()).ifPresent(a -> assertTrue(a.characterRangeTable().isEmpty()));
}
@Test // JDK-8361908
void testFilterMixedExceptionCatch() {
var cc = ClassFile.of(ClassFile.DeadLabelsOption.DROP_DEAD_LABELS);
var code = cc.parse(cc.build(CD_Void, clb ->
clb.withMethodBody("m", MTD_void, 0, cob -> {
cob.return_();
var l = cob.newBoundLabel();
cob.pop().return_();
cob.exceptionCatch(cob.startLabel(), l, l, Optional.empty());
cob.exceptionCatch(cob.newLabel(), l, l, CD_Exception);
}))).methods().get(0).code().get();
assertEquals(1, code.exceptionHandlers().size(), () -> code.exceptionHandlers().toString());
assertEquals(Optional.empty(), code.exceptionHandlers().getFirst().catchType());
}
@ParameterizedTest
@MethodSource("deadLabelFragments")
void testThrowOnDeadLabels(Consumer<CodeBuilder> fragment) {