Skip to content

Commit 70cccf1

Browse files
committed
Expand RedundantTryCatchRemovingTransformer to cover cases of handler blocks with types provably never thrown in the workspace
1 parent 0b0463f commit 70cccf1

File tree

5 files changed

+679
-337
lines changed

5 files changed

+679
-337
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package software.coley.recaf.services.deobfuscation.transform.generic;
2+
3+
import jakarta.annotation.Nonnull;
4+
import jakarta.enterprise.context.Dependent;
5+
import jakarta.inject.Inject;
6+
import org.objectweb.asm.ClassReader;
7+
import org.objectweb.asm.MethodVisitor;
8+
import org.objectweb.asm.Opcodes;
9+
import software.coley.recaf.info.ClassInfo;
10+
import software.coley.recaf.info.JvmClassInfo;
11+
import software.coley.recaf.info.properties.builtin.ThrowableProperty;
12+
import software.coley.recaf.path.ClassPathNode;
13+
import software.coley.recaf.services.inheritance.InheritanceGraph;
14+
import software.coley.recaf.services.inheritance.InheritanceGraphService;
15+
import software.coley.recaf.services.transform.JvmClassTransformer;
16+
import software.coley.recaf.services.transform.JvmTransformerContext;
17+
import software.coley.recaf.services.transform.TransformationException;
18+
import software.coley.recaf.util.visitors.SkippingClassVisitor;
19+
import software.coley.recaf.util.visitors.SkippingMethodVisitor;
20+
import software.coley.recaf.workspace.model.Workspace;
21+
import software.coley.recaf.workspace.model.bundle.JvmClassBundle;
22+
import software.coley.recaf.workspace.model.resource.WorkspaceResource;
23+
24+
import java.util.HashSet;
25+
import java.util.Set;
26+
27+
/**
28+
* A transformer that collects information about exceptions in the workspace.
29+
*
30+
* @author Matt Coley
31+
*/
32+
@Dependent
33+
public class ExceptionCollectionTransformer implements JvmClassTransformer, Opcodes {
34+
private final Set<String> thrownExceptions = new HashSet<>();
35+
private final InheritanceGraphService graphService;
36+
private InheritanceGraph inheritanceGraph;
37+
38+
@Inject
39+
public ExceptionCollectionTransformer(@Nonnull InheritanceGraphService graphService) {
40+
this.graphService = graphService;
41+
42+
thrownExceptions.add("java/lang/Throwable");
43+
thrownExceptions.add("java/lang/Exception");
44+
}
45+
46+
@Override
47+
public void setup(@Nonnull JvmTransformerContext context, @Nonnull Workspace workspace) {
48+
inheritanceGraph = graphService.getOrCreateInheritanceGraph(workspace);
49+
}
50+
51+
@Override
52+
public void transform(@Nonnull JvmTransformerContext context, @Nonnull Workspace workspace,
53+
@Nonnull WorkspaceResource resource, @Nonnull JvmClassBundle bundle,
54+
@Nonnull JvmClassInfo initialClassState) throws TransformationException {
55+
initialClassState.getClassReader().accept(new SkippingClassVisitor() {
56+
@Override
57+
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
58+
return new SkippingMethodVisitor() {
59+
@Override
60+
public void visitTypeInsn(int opcode, String type) {
61+
// Collect "new T" where "T" is a throwable type.
62+
if (opcode != NEW)
63+
return;
64+
ClassPathNode path = workspace.findClass(false, type);
65+
if (path == null)
66+
return;
67+
if (ThrowableProperty.get(path.getValue()) || inheritanceGraph.isAssignableFrom("java/lang/Throwable", type)) {
68+
// The constructed type is an exception type,
69+
// so we should add it and all parents to the known thrown types.
70+
ClassInfo exInfo = path.getValue();
71+
while (thrownExceptions.add(exInfo.getName()) && exInfo.getSuperName() != null) {
72+
path = workspace.findClass(false, exInfo.getSuperName());
73+
if (path == null)
74+
break;
75+
}
76+
}
77+
}
78+
};
79+
}
80+
}, ClassReader.SKIP_FRAMES | ClassReader.SKIP_DEBUG);
81+
}
82+
83+
@Nonnull
84+
@Override
85+
public String name() {
86+
return "Exception metadata collection";
87+
}
88+
89+
/**
90+
* @return Set of all exception types thrown in code defined in the workspace.
91+
*/
92+
@Nonnull
93+
public Set<String> getThrownExceptions() {
94+
return thrownExceptions;
95+
}
96+
}

0 commit comments

Comments
 (0)