fix: nested try catches with overlap try blocks (#1374)(PR #1375)

* fix: nested try catch decompilation failed (#1374)
* add tests and sort handlers

Co-authored-by: Skylot <skylot@gmail.com>
This commit is contained in:
xxjy
2022-02-10 04:55:15 +08:00
committed by GitHub
parent 8d5554f1b5
commit 7a5a2fcd84
4 changed files with 48 additions and 4 deletions
@@ -1,5 +1,6 @@
package jadx.core.dex.trycatch;
import java.util.Comparator;
import java.util.List;
import jadx.api.plugins.input.data.attributes.IJadxAttribute;
@@ -8,9 +9,14 @@ import jadx.core.utils.Utils;
public class CatchAttr implements IJadxAttribute {
public static CatchAttr build(List<ExceptionHandler> handlers) {
handlers.sort(Comparator.comparingInt(ExceptionHandler::getHandlerOffset));
return new CatchAttr(handlers);
}
private final List<ExceptionHandler> handlers;
public CatchAttr(List<ExceptionHandler> handlers) {
private CatchAttr(List<ExceptionHandler> handlers) {
this.handlers = handlers;
}
@@ -55,7 +55,7 @@ public class AttachTryCatchVisitor extends AbstractVisitor {
if (handlers.isEmpty()) {
continue;
}
markTryBounds(insnByOffset, tryData, new CatchAttr(handlers));
markTryBounds(insnByOffset, tryData, CatchAttr.build(handlers));
}
}
@@ -96,7 +96,7 @@ public class AttachTryCatchVisitor extends AbstractVisitor {
if (existAttr != null) {
// merge handlers
List<ExceptionHandler> handlers = Utils.concat(existAttr.getHandlers(), catchAttr.getHandlers());
insn.addAttr(new CatchAttr(handlers));
insn.addAttr(CatchAttr.build(handlers));
} else {
insn.addAttr(catchAttr);
}
@@ -126,7 +126,7 @@ public class BlockExceptionHandler {
commonCatchAttr = catchAttr;
continue;
}
if (commonCatchAttr != catchAttr) {
if (!commonCatchAttr.equals(catchAttr)) {
return null;
}
}
@@ -0,0 +1,38 @@
package jadx.tests.integration.trycatch;
import jadx.tests.api.IntegrationTest;
import jadx.tests.api.extensions.profiles.TestProfile;
import jadx.tests.api.extensions.profiles.TestWithProfiles;
import static jadx.tests.api.utils.assertj.JadxAssertions.assertThat;
public class TestNestedTryCatch2 extends IntegrationTest {
public static class TestCls {
public void test() {
try {
try {
call();
call();
} catch (Exception e) {
exc(e);
}
} catch (Exception e) {
exc(e);
}
}
private void call() {
}
private void exc(Exception e) {
}
}
@TestWithProfiles({ TestProfile.JAVA8, TestProfile.DX_J8 })
public void test() {
assertThat(getClassNode(TestCls.class))
.code()
.countString(2, "} catch (Exception ");
}
}