fix: improve handler path check for regions
This commit is contained in:
@@ -117,12 +117,12 @@ public class ProcessTryCatchRegions extends AbstractRegionVisitor {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean isHandlerPath(TryCatchBlockAttr tb, IContainer cont) {
|
||||
private static boolean isHandlerPath(TryCatchBlockAttr tb, IContainer container) {
|
||||
for (ExceptionHandler h : tb.getHandlers()) {
|
||||
BlockNode handlerBlock = h.getHandlerBlock();
|
||||
if (handlerBlock != null
|
||||
&& !handlerBlock.contains(AFlag.REMOVE)
|
||||
&& RegionUtils.hasPathThroughBlock(handlerBlock, cont)) {
|
||||
&& RegionUtils.isPathExists(handlerBlock, container)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,8 @@ import jadx.core.dex.nodes.IRegion;
|
||||
import jadx.core.dex.nodes.InsnNode;
|
||||
import jadx.core.dex.nodes.MethodNode;
|
||||
import jadx.core.dex.regions.Region;
|
||||
import jadx.core.dex.regions.SwitchRegion;
|
||||
import jadx.core.dex.regions.TryCatchRegion;
|
||||
import jadx.core.dex.regions.loops.LoopRegion;
|
||||
import jadx.core.dex.trycatch.CatchAttr;
|
||||
import jadx.core.dex.trycatch.ExceptionHandler;
|
||||
@@ -109,19 +111,31 @@ public class RegionUtils {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (container instanceof IBranchRegion) {
|
||||
return null;
|
||||
if (container instanceof IConditionRegion) {
|
||||
return ListUtils.firstOrNull(((IConditionRegion) container).getConditionBlocks());
|
||||
}
|
||||
if (container instanceof TryCatchRegion) {
|
||||
return getFirstBlockNode(((TryCatchRegion) container).getTryRegion());
|
||||
}
|
||||
if (container instanceof SwitchRegion) {
|
||||
return ((SwitchRegion) container).getHeader();
|
||||
}
|
||||
if (container instanceof IRegion) {
|
||||
List<IContainer> blocks = ((IRegion) container).getSubBlocks();
|
||||
if (blocks.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return getFirstBlockNode(blocks.get(0));
|
||||
return getFirstBlockNode(((IRegion) container).getSubBlocks());
|
||||
}
|
||||
throw new JadxRuntimeException(unknownContainerType(container));
|
||||
}
|
||||
|
||||
private static @Nullable BlockNode getFirstBlockNode(List<IContainer> containers) {
|
||||
for (IContainer cont : containers) {
|
||||
BlockNode firstBlockNode = getFirstBlockNode(cont);
|
||||
if (firstBlockNode != null) {
|
||||
return firstBlockNode;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static int getFirstSourceLine(IContainer container) {
|
||||
if (container instanceof IBlock) {
|
||||
return BlockUtils.getFirstSourceLine((IBlock) container);
|
||||
@@ -586,6 +600,18 @@ public class RegionUtils {
|
||||
throw new JadxRuntimeException(unknownContainerType(cont));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if path exists from block to container start.
|
||||
* Return false if block is inside container.
|
||||
*/
|
||||
public static boolean isPathExists(BlockNode block, IContainer container) {
|
||||
BlockNode firstBlock = RegionUtils.getFirstBlockNode(container);
|
||||
if (firstBlock != null) {
|
||||
return BlockUtils.isPathExists(block, firstBlock);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected static String unknownContainerType(IContainer container) {
|
||||
if (container == null) {
|
||||
return "Null container variable";
|
||||
|
||||
@@ -8,10 +8,12 @@ import org.junit.jupiter.api.Test;
|
||||
|
||||
import jadx.NotYetImplemented;
|
||||
import jadx.tests.api.IntegrationTest;
|
||||
import jadx.tests.api.utils.assertj.JadxAssertions;
|
||||
|
||||
import static jadx.tests.api.utils.assertj.JadxAssertions.assertThat;
|
||||
|
||||
public class TestTryCatchFinally8 extends IntegrationTest {
|
||||
|
||||
@SuppressWarnings({ "ResultOfMethodCallIgnored", "TryFinallyCanBeTryWithResources", "DataFlowIssue" })
|
||||
public static class TestCls {
|
||||
public Object test(Object obj) {
|
||||
File file = new File("r");
|
||||
@@ -42,20 +44,12 @@ public class TestTryCatchFinally8 extends IntegrationTest {
|
||||
@Test
|
||||
@NotYetImplemented("Fix merged catch blocks (shared code between catches)")
|
||||
public void test() {
|
||||
JadxAssertions.assertThat(getClassNode(TestCls.class))
|
||||
assertThat(getClassNode(TestCls.class))
|
||||
.code()
|
||||
.contains("try {")
|
||||
.contains("} catch (IOException e) {")
|
||||
.contains("} finally {")
|
||||
.contains("file.delete();");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test2() {
|
||||
disableCompilation();
|
||||
JadxAssertions.assertThat(getClassNode(TestCls.class))
|
||||
.code()
|
||||
.contains("output = new FileOutputStream(file);")
|
||||
.contains("} catch (IOException e) {");
|
||||
.containsOne("FileOutputStream output = null;")
|
||||
.countString(2, "try {")
|
||||
.countString(2, "} catch (IOException e")
|
||||
.containsOne("} finally {")
|
||||
.containsOne("file.delete();");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user