@Override public int getSuccNodeCount(CGNode n) { Iterator<CGNode> tmp = cg.getSuccNodes(n); int cnt = 0; while (tmp.hasNext()) { CGNode no = tmp.next(); if (keep.contains(no) && !removedEdge(n, no)) { cnt++; } } return cnt; }
@Override public int getSuccNodeCount(CGNode n) { Iterator<CGNode> tmp = cg.getSuccNodes(n); int cnt = 0; while (tmp.hasNext()) { CGNode no = tmp.next(); if (keep.contains(no) && !removedEdge(n, no)) { cnt++; } } return cnt; }
@Override public Iterator<CGNode> getSuccNodes(CGNode n) { Iterator<CGNode> tmp = cg.getSuccNodes(n); Collection<CGNode> col = new LinkedList<>(); while (tmp.hasNext()) { CGNode no = tmp.next(); if (keep.contains(no) && !removedEdge(n, no)) { col.add(no); } } return col.iterator(); }
@Override public Iterator<CGNode> getSuccNodes(CGNode n) { Iterator<CGNode> tmp = cg.getSuccNodes(n); Collection<CGNode> col = new LinkedList<>(); while (tmp.hasNext()) { CGNode no = tmp.next(); if (keep.contains(no) && !removedEdge(n, no)) { col.add(no); } } return col.iterator(); }
private void addDepth(CGNode node) { LinkedList<CGNode> A = new LinkedList<>(); LinkedList<CGNode> B = new LinkedList<>(); int i = depth; A.add(node); while (i > 0) { for (CGNode n : A) { Iterator<CGNode> it = cg.getSuccNodes(n); while (it.hasNext()) { B.add(it.next()); } } if (DEBUG) { System.out.println("Tiefe: " + B); } keep.addAll(B); A.clear(); A.addAll(B); B.clear(); i--; } }
private void addDepth(CGNode node) { LinkedList<CGNode> A = new LinkedList<>(); LinkedList<CGNode> B = new LinkedList<>(); int i = depth; A.add(node); while (i > 0) { for (CGNode n : A) { Iterator<CGNode> it = cg.getSuccNodes(n); while (it.hasNext()) { B.add(it.next()); } } if (DEBUG) { System.out.println("Tiefe: " + B); } keep.addAll(B); A.clear(); A.addAll(B); B.clear(); i--; } }
private void dfs(CGNode root) { visited.addLast(root); Iterator<CGNode> it = cg.getSuccNodes(root); while (it.hasNext()) { CGNode next = it.next(); if (!marked.contains(next)) { marked.add(next); dfs(next); } else { if (keep.contains(next)) { keep.addAll(visited); } } } if (pruningPolicy.check(root)) { keep.addAll(visited); addDepth(root); } visited.removeLast(); }
private void dfs(CGNode root) { visited.addLast(root); Iterator<CGNode> it = cg.getSuccNodes(root); while (it.hasNext()) { CGNode next = it.next(); if (!marked.contains(next)) { marked.add(next); dfs(next); } else { if (keep.contains(next)) { keep.addAll(visited); } } } if (pruningPolicy.check(root)) { keep.addAll(visited); addDepth(root); } visited.removeLast(); }
private static Collection<CGNode> getSuccNodes(CallGraph cg, Collection<CGNode> nodes) { Set<CGNode> succNodes = HashSetFactory.make(); for (CGNode newInstanceNode : nodes) { Iterator<? extends CGNode> succNodesIter = cg.getSuccNodes(newInstanceNode); while (succNodesIter.hasNext()) { succNodes.add(succNodesIter.next()); } } return succNodes; }
@Override public Iterator<MethodReference> getSuccNodes(MethodReference N) { Set<MethodReference> succ = HashSetFactory.make(10); MethodReference methodReference = N; for (CGNode node : cg.getNodes(methodReference)) for (CGNode p : Iterator2Iterable.make(cg.getSuccNodes(node))) succ.add(p.getMethod().getReference()); return succ.iterator(); }
/** * Verifies that none of the nodes that match the source description has an edge to any of the nodes that match the destination * description. (Used for checking for false connections in the callgraph) */ protected void verifyNoEdges(CallGraph CG, String sourceDescription, String destDescription) { Collection<CGNode> sources = getNodes(CG, sourceDescription); Collection<CGNode> dests = getNodes(CG, destDescription); for (Object source : sources) { for (Object dest : dests) { for (CGNode n : Iterator2Iterable.make(CG.getSuccNodes((CGNode) source))) { if (n.equals(dest)) { Assert.fail("Found a link from " + source + " to " + dest); } } } } }
@Test public void testFunctionDotCall() throws IOException, IllegalArgumentException, CancelException, WalaException { CallGraph cg = JSCallGraphBuilderUtil.makeScriptCG("tests", "function_call.js"); for (CGNode n : cg) { if (n.getMethod().getName().toString().equals("call4")) { Assert.assertEquals(2, cg.getSuccNodeCount(n)); // ugh List<CGNode> succs = Iterator2Collection.toList(cg.getSuccNodes(n)); Assert .assertEquals( "[Node: <Code body of function Lfunction_call.js/foo> Context: Everywhere, Node: <Code body of function Lfunction_call.js/bar> Context: Everywhere]", succs.toString()); } } }
/** * Check that when analyzing Reflect5, successors of newInstance do not * include a Reflect5$A ctor */ @Test public void testReflect5() throws IOException, ClassHierarchyException, IllegalArgumentException, CancelException { AnalysisScope scope = findOrCreateAnalysisScope(); IClassHierarchy cha = findOrCreateCHA(scope); Iterable<Entrypoint> entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, TestConstants.REFLECT5_MAIN); AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); CallGraph cg = CallGraphTestUtil.buildZeroOneCFA(options, new AnalysisCacheImpl(), cha, scope, false); TypeReference tr = TypeReference.findOrCreate(ClassLoaderReference.Application, "Ljava/lang/Class"); MethodReference mr = MethodReference.findOrCreate(tr, "newInstance", "()Ljava/lang/Object;"); Set<CGNode> newInstanceNodes = cg.getNodes(mr); Set<CGNode> succNodes = HashSetFactory.make(); for (CGNode newInstanceNode : newInstanceNodes) { Iterator<? extends CGNode> succNodesIter = cg.getSuccNodes(newInstanceNode); while (succNodesIter.hasNext()) { succNodes.add(succNodesIter.next()); } } TypeReference extraneousTR = TypeReference.findOrCreate(ClassLoaderReference.Application, "Lreflection/Reflect5$A"); MethodReference extraneousMR = MethodReference.findOrCreate(extraneousTR, "<init>", "()V"); Set<CGNode> extraneousNodes = cg.getNodes(extraneousMR); succNodes.retainAll(extraneousNodes); Assert.assertTrue(succNodes.isEmpty()); }
/** * Check that when analyzing Reflect6, successors of newInstance do not * include a Reflect6$A ctor */ @Test public void testReflect6() throws IOException, ClassHierarchyException, IllegalArgumentException, CancelException { AnalysisScope scope = findOrCreateAnalysisScope(); IClassHierarchy cha = findOrCreateCHA(scope); Iterable<Entrypoint> entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, TestConstants.REFLECT6_MAIN); AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); CallGraph cg = CallGraphTestUtil.buildZeroOneCFA(options, new AnalysisCacheImpl(), cha, scope, false); TypeReference tr = TypeReference.findOrCreate(ClassLoaderReference.Application, "Ljava/lang/Class"); MethodReference mr = MethodReference.findOrCreate(tr, "newInstance", "()Ljava/lang/Object;"); Set<CGNode> newInstanceNodes = cg.getNodes(mr); Set<CGNode> succNodes = HashSetFactory.make(); for (CGNode newInstanceNode : newInstanceNodes) { Iterator<? extends CGNode> succNodesIter = cg.getSuccNodes(newInstanceNode); while (succNodesIter.hasNext()) { succNodes.add(succNodesIter.next()); } } TypeReference extraneousTR = TypeReference.findOrCreate(ClassLoaderReference.Application, "Lreflection/Reflect6$A"); MethodReference extraneousMR = MethodReference.findOrCreate(extraneousTR, "<init>", "(I)V"); Set<CGNode> extraneousNodes = cg.getNodes(extraneousMR); succNodes.retainAll(extraneousNodes); Assert.assertTrue(succNodes.isEmpty()); }
/** * Check that when analyzing Reflect4, successors of newInstance() do not * include FilePermission ctor. */ @Test public void testReflect4() throws IOException, ClassHierarchyException, IllegalArgumentException, CancelException { AnalysisScope scope = findOrCreateAnalysisScope(); IClassHierarchy cha = findOrCreateCHA(scope); Iterable<Entrypoint> entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, TestConstants.REFLECT4_MAIN); AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); CallGraph cg = CallGraphTestUtil.buildZeroOneCFA(options, new AnalysisCacheImpl(), cha, scope, false); TypeReference tr = TypeReference.findOrCreate(ClassLoaderReference.Application, "Ljava/lang/Class"); MethodReference mr = MethodReference.findOrCreate(tr, "newInstance", "()Ljava/lang/Object;"); Set<CGNode> newInstanceNodes = cg.getNodes(mr); Set<CGNode> succNodes = HashSetFactory.make(); for (CGNode newInstanceNode : newInstanceNodes) { Iterator<? extends CGNode> succNodesIter = cg.getSuccNodes(newInstanceNode); while (succNodesIter.hasNext()) { succNodes.add(succNodesIter.next()); } } TypeReference extraneousTR = TypeReference.findOrCreate(ClassLoaderReference.Application, "Ljava/io/FilePermission"); MethodReference extraneousMR = MethodReference.findOrCreate(extraneousTR, "<init>", "(Ljava/lang/String;Ljava/lang/String;)V"); Set<CGNode> extraneousNodes = cg.getNodes(extraneousMR); succNodes.retainAll(extraneousNodes); Assert.assertTrue(succNodes.isEmpty()); }
/** * Check that when analyzing Reflect3, the successors of newInstance do not * include reflection/Reflect3$Hash */ @Test public void testReflect3() throws IOException, ClassHierarchyException, IllegalArgumentException, CancelException { AnalysisScope scope = findOrCreateAnalysisScope(); IClassHierarchy cha = findOrCreateCHA(scope); Iterable<Entrypoint> entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, TestConstants.REFLECT3_MAIN); AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); CallGraph cg = CallGraphTestUtil.buildZeroOneCFA(options, new AnalysisCacheImpl(), cha, scope, false); TypeReference tr = TypeReference.findOrCreate(ClassLoaderReference.Application, "Ljava/lang/Class"); MethodReference mr = MethodReference.findOrCreate(tr, "newInstance", "()Ljava/lang/Object;"); Set<CGNode> newInstanceNodes = cg.getNodes(mr); Set<CGNode> succNodes = HashSetFactory.make(); for (CGNode newInstanceNode : newInstanceNodes) { Iterator<? extends CGNode> succNodesIter = cg.getSuccNodes(newInstanceNode); while (succNodesIter.hasNext()) { succNodes.add(succNodesIter.next()); } } TypeReference extraneousTR = TypeReference.findOrCreate(ClassLoaderReference.Application, "Lreflection/Reflect3$Hash"); IClass hashClass = cha.lookupClass(extraneousTR); assert hashClass != null; MethodReference extraneousMR = MethodReference.findOrCreate(extraneousTR, "<init>", "()V"); Set<CGNode> extraneousNodes = cg.getNodes(extraneousMR); succNodes.retainAll(extraneousNodes); Assert.assertTrue(succNodes.isEmpty()); }
@Test public void testSystemProperties() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException { AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.WALA_TESTDATA, CallGraphTestUtil.REGRESSION_EXCLUSIONS); ClassHierarchy cha = ClassHierarchyFactory.make(scope); Iterable<Entrypoint> entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, "LstaticInit/TestSystemProperties"); AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); SSAPropagationCallGraphBuilder builder = Util.makeZeroCFABuilder(Language.JAVA, options, new AnalysisCacheImpl(), cha, scope); CallGraph cg = builder.makeCallGraph(options); for (CGNode n : cg) { if (n.toString().equals("Node: < Application, LstaticInit/TestSystemProperties, main([Ljava/lang/String;)V > Context: Everywhere")) { boolean foundToCharArray = false; for (CGNode callee : Iterator2Iterable.make(cg.getSuccNodes(n))) { if (callee.getMethod().getName().toString().equals("toCharArray")) { foundToCharArray = true; break; } } Assert.assertTrue(foundToCharArray); break; } } }
/** * Test that when analyzing Reflect18, the call graph includes a node for * java.lang.Integer.toString() */ @Test public void testReflect18() throws WalaException, IllegalArgumentException, CancelException, IOException { AnalysisScope scope = findOrCreateAnalysisScope(); IClassHierarchy cha = findOrCreateCHA(scope); Iterable<Entrypoint> entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, TestConstants.REFLECT18_MAIN); AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); CallGraph cg = CallGraphTestUtil.buildZeroOneCFA(options, new AnalysisCacheImpl(), cha, scope, false); TypeReference tr = TypeReference.findOrCreate(ClassLoaderReference.Application, "Lreflection/Helper"); MethodReference mr = MethodReference.findOrCreate(tr, "t", "(Ljava/lang/Integer;)V"); CGNode node = cg.getNode(cg.getClassHierarchy().resolveMethod(mr), Everywhere.EVERYWHERE); Assert.assertEquals(1, cg.getSuccNodeCount(node)); CGNode succ = cg.getSuccNodes(node).next(); Assert.assertEquals("Node: < Primordial, Ljava/lang/Integer, toString()Ljava/lang/String; > Context: Everywhere", succ.toString()); }
public static CGNode findMainMethod(CallGraph cg) { Descriptor d = Descriptor.findOrCreateUTF8("([Ljava/lang/String;)V"); Atom name = Atom.findOrCreateUnicodeAtom("main"); for (CGNode n : Iterator2Iterable.make(cg.getSuccNodes(cg.getFakeRootNode()))) { if (n.getMethod().getName().equals(name) && n.getMethod().getDescriptor().equals(d)) { return n; } } Assertions.UNREACHABLE("failed to find method"); return null; }
private static CGNode findMethod(CallGraph cg, Descriptor d, Atom name) { for (CGNode n : Iterator2Iterable.make(cg.getSuccNodes(cg.getFakeRootNode()))) { if (n.getMethod().getName().equals(name) && n.getMethod().getDescriptor().equals(d)) { return n; } } // if it's not a successor of fake root, just iterate over everything for (CGNode n : cg) { if (n.getMethod().getName().equals(name) && n.getMethod().getDescriptor().equals(d)) { return n; } } Assertions.UNREACHABLE("failed to find method " + name); return null; }