fix: avoid more false positive throws (PR #2752)

Update MethodThrowsVisitor.java
This commit is contained in:
ewt45
2026-01-22 02:43:00 +08:00
committed by GitHub
parent c677901aa5
commit 54265e34e5
2 changed files with 20 additions and 40 deletions
@@ -1,7 +1,6 @@
package jadx.core.dex.visitors;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -180,7 +179,9 @@ public class MethodThrowsVisitor extends AbstractVisitor {
MethodThrowsAttr cAttr = cMth.get(AType.METHOD_THROWS);
MethodThrowsAttr attr = mth.get(AType.METHOD_THROWS);
if (attr != null && cAttr != null && !cAttr.getList().isEmpty()) {
attr.getList().addAll(filterExceptions(cAttr.getList(), excludedExceptions));
for (String argTypeStr : cAttr.getList()) {
visitThrows(mth, ArgType.object(argTypeStr), excludedExceptions);
}
}
} else {
ClspClass clsDetails = root.getClsp().getClsDetails(classInfo.getType());
@@ -189,7 +190,9 @@ public class MethodThrowsVisitor extends AbstractVisitor {
if (cMth != null && cMth.getThrows() != null && !cMth.getThrows().isEmpty()) {
MethodThrowsAttr attr = mth.get(AType.METHOD_THROWS);
if (attr != null) {
attr.getList().addAll(filterExceptions(cMth.getThrows(), excludedExceptions));
for (ArgType argType : cMth.getThrows()) {
visitThrows(mth, argType, excludedExceptions);
}
}
}
}
@@ -251,41 +254,6 @@ public class MethodThrowsVisitor extends AbstractVisitor {
return root.getClsp().isImplements(type.getObject(), baseType.getObject());
}
private Collection<String> filterExceptions(Set<String> exceptions, Set<String> excludedExceptions) {
Set<String> filteredExceptions = new HashSet<>();
for (String exception : exceptions) {
boolean filtered = false;
for (String excluded : excludedExceptions) {
filtered = isBaseException(exception, excluded);
if (filtered) {
break;
}
}
if (!filtered) {
filteredExceptions.add(exception);
}
}
return filteredExceptions;
}
private Collection<String> filterExceptions(Collection<ArgType> exceptionArgTypes, Set<String> excludedExceptions) {
Set<String> filteredExceptions = new HashSet<>();
for (ArgType exceptionArgType : exceptionArgTypes) {
boolean filtered = false;
String exception = exceptionArgType.getObject();
for (String excluded : excludedExceptions) {
filtered = isBaseException(exception, excluded);
if (filtered) {
break;
}
}
if (!filtered) {
filteredExceptions.add(exception);
}
}
return filteredExceptions;
}
private @Nullable MethodNode searchOverriddenMethod(ClassNode cls, MethodInfo mth, String signature) {
// search by exact full signature (with return value) to fight obfuscation (see test
// 'TestOverrideWithSameName')
@@ -74,6 +74,13 @@ public class TestThrows extends IntegrationTest {
}
}
public int doSomething3(int i) throws IllegalArgumentException {
if (i < 0) {
throw new IllegalArgumentException();
}
return 1;
}
public void noThrownExceptions1(InputStream i1) {
try {
i1.close();
@@ -87,6 +94,11 @@ public class TestThrows extends IntegrationTest {
} catch (IOException ignore) {
}
}
public void noThrownExceptions3() {
int i = doSomething3(0);
System.out.print(i);
}
}
@Test
@@ -104,7 +116,7 @@ public class TestThrows extends IntegrationTest {
.containsOne("mergeThrownExceptions() throws IOException {")
.containsOne("rethrowThrowable() {")
.containsOne("noThrownExceptions1(InputStream i1) {")
.containsOne("noThrownExceptions2() {");
.containsOne("noThrownExceptions2() {")
.containsOne("noThrownExceptions3() {");
}
}