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