public void RemoveUnavailableCalls(IndexDb index) { var mergedRefs = new HashSet <string>(); var entryNodes = EntryNodes.Values.Where(x => x.OutNodes.Count > 0).ToList(); foreach (var entryNode in entryNodes) { foreach (var ref1 in index.AssemblyReferences[entryNode.AssemblyName]) { mergedRefs.Add(ref1); } } var processingNodes = new Queue <ICallGraphNode>(entryNodes); while (processingNodes.Count > 0) { var node = processingNodes.Dequeue(); if (node.OutNodes.Count == 0) { continue; // this is a sensitive sink } for (var i = node.OutNodes.Count - 1; i >= 0; i--) { var outNode = node.OutNodes[i]; if (outNode.OutNodes.Count > 0) // outNode is not sensitive sink { if (node.AssemblyName != outNode.AssemblyName && !mergedRefs.Contains(outNode.AssemblyName)) { node.OutNodes.RemoveAt(i); outNode.InNodes.Remove(node); if (outNode.InNodes.Count == 0) { // outNode is unavailable from entry points RemoveUnavailableNodesFrom(outNode); } } else { processingNodes.Enqueue(outNode); } } } // do it only for non-sensitive sinks if (node.OutNodes.Count == 0) { RemoveUnavailableNodesTo(node); } } }
public CallGraphBuilder(IndexDb index) { this.index = index; stat.IgnoredOpcodes = new HashSet <Code>(); }