From e24abb10cc330cfcee0f741865e218d01e63a453 Mon Sep 17 00:00:00 2001 From: Manu Sridharan Date: Fri, 26 Aug 2022 15:14:02 -0700 Subject: [PATCH] Add new reflection test (#1117) Based on discussion in #1116, in particular https://github.com/wala/WALA/issues/1116#issuecomment-1224480683 --- .../core/tests/callGraph/ReflectionTest.java | 26 +++++++++++++++++++ .../reflection/ForNameThrownExceptions.java | 22 ++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 com.ibm.wala.core/src/testSubjects/java/reflection/ForNameThrownExceptions.java diff --git a/com.ibm.wala.core/src/test/java/com/ibm/wala/core/tests/callGraph/ReflectionTest.java b/com.ibm.wala.core/src/test/java/com/ibm/wala/core/tests/callGraph/ReflectionTest.java index 5979aa2008..df54eac119 100644 --- a/com.ibm.wala.core/src/test/java/com/ibm/wala/core/tests/callGraph/ReflectionTest.java +++ b/com.ibm.wala.core/src/test/java/com/ibm/wala/core/tests/callGraph/ReflectionTest.java @@ -18,6 +18,7 @@ import com.ibm.wala.core.util.warnings.Warnings; import com.ibm.wala.ipa.callgraph.AnalysisCacheImpl; import com.ibm.wala.ipa.callgraph.AnalysisOptions; +import com.ibm.wala.ipa.callgraph.AnalysisOptions.ReflectionOptions; import com.ibm.wala.ipa.callgraph.AnalysisScope; import com.ibm.wala.ipa.callgraph.CGNode; import com.ibm.wala.ipa.callgraph.CallGraph; @@ -41,11 +42,13 @@ import com.ibm.wala.util.WalaException; import com.ibm.wala.util.collections.HashSetFactory; import com.ibm.wala.util.collections.Iterator2Iterable; +import com.ibm.wala.util.collections.Iterator2List; import com.ibm.wala.util.collections.Pair; import com.ibm.wala.util.intset.OrdinalSet; import java.io.IOException; import java.util.Collection; import java.util.Iterator; +import java.util.List; import java.util.Optional; import java.util.Set; import org.junit.AfterClass; @@ -827,4 +830,27 @@ public void testGetMethodContext() cgn = cg.getNodes(mcbar); Assert.assertEquals(1, cgn.size()); } + + @Test + public void testForNameThrownExceptions() + throws WalaException, IllegalArgumentException, CancelException, IOException { + AnalysisScope scope = findOrCreateAnalysisScope(); + IClassHierarchy cha = findOrCreateCHA(scope); + Iterable entrypoints = + com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints( + cha, "Lreflection/ForNameThrownExceptions"); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + options.setReflectionOptions(ReflectionOptions.NONE); + CallGraph cg = CallGraphTestUtil.buildZeroCFA(options, new AnalysisCacheImpl(), cha, false); + IMethod mainMethod = entrypoints.iterator().next().getMethod(); + List mainCallees = + Iterator2List.toList(cg.getSuccNodes(cg.getNode(mainMethod, Everywhere.EVERYWHERE))); + Assert.assertTrue(mainCallees.stream().anyMatch(n -> n.toString().contains("getMessage"))); + options.setReflectionOptions(ReflectionOptions.STRING_ONLY); + cg = CallGraphTestUtil.buildZeroCFA(options, new AnalysisCacheImpl(), cha, false); + mainCallees = + Iterator2List.toList(cg.getSuccNodes(cg.getNode(mainMethod, Everywhere.EVERYWHERE))); + // getMessage() should _not_ be a callee with reflection handling enabled + Assert.assertFalse(mainCallees.stream().anyMatch(n -> n.toString().contains("getMessage"))); + } } diff --git a/com.ibm.wala.core/src/testSubjects/java/reflection/ForNameThrownExceptions.java b/com.ibm.wala.core/src/testSubjects/java/reflection/ForNameThrownExceptions.java new file mode 100644 index 0000000000..745dc9edbf --- /dev/null +++ b/com.ibm.wala.core/src/testSubjects/java/reflection/ForNameThrownExceptions.java @@ -0,0 +1,22 @@ +package reflection; + +public class ForNameThrownExceptions { + + static class MyClass { + public String sayHello() { + return "Hello from MyClass!"; + } + } + + public static void main(String[] args) { + try { + // This call to Class.forName() can be resolved by WALA's reflection handling. When + // it is resolved, the resulting synthetic model of Class.forName() cannot throw + // a ClassNotFoundException. Hence, no Exception values flow to e, and the call + // to e.getMessage() in the catch block has no callees + Class clazz = Class.forName("reflection.ForNameThrownExceptions$MyClass"); + } catch (Exception e) { + System.out.println(e.getMessage()); + } + } +}