angr/analyses/cfg/cfg_utils.py
def quasi_topological_sort_nodes(graph, nodes=None):
        """
        Sort a given set of nodes from a graph based on the following rules:

        # - if A -> B and not B -> A, then we have A < B
        # - if A -> B and B -> A, then the ordering is undefined

        Following the above rules gives us a quasi-topological sorting of nodes in the graph. It also works for cyclic
        graphs.

        :param networkx.DiGraph graph: A local transition graph of the function.
        :param iterable nodes: A list of nodes to sort. None if you want to sort all nodes inside the graph.
        :return: A list of ordered nodes.
        :rtype: list
        """

        # fast path for single node graphs
        if graph.number_of_nodes() == 1:
            return list(graph.nodes())

        # make a copy to the graph since we are gonna modify it
        graph_copy = networkx.DiGraph()

        # find all strongly connected components in the graph
        sccs = [ scc for scc in networkx.strongly_connected_components(graph) if len(scc) > 1 ]

        # collapse all strongly connected components
        for src, dst in graph.edges():
            scc_index = CFGUtils._components_index_node(sccs, src)
            if scc_index is not None:
                src = SCCPlaceholder(scc_index)
            scc_index = CFGUtils._components_index_node(sccs, dst)
            if scc_index is not None:
                dst = SCCPlaceholder(scc_index)

            if isinstance(src, SCCPlaceholder) and isinstance(dst, SCCPlaceholder) and src == dst:
                continue
            if src == dst:
                continue

            graph_copy.add_edge(src, dst)

        # add loners
        out_degree_zero_nodes = [node for (node, degree) in graph.out_degree() if degree == 0]
        for node in out_degree_zero_nodes:
            if graph.in_degree(node) == 0:
                graph_copy.add_node(node)

        # topological sort on acyclic graph `graph_copy`
        tmp_nodes = networkx.topological_sort(graph_copy)

        ordered_nodes = [ ]
        for n in tmp_nodes:
            if isinstance(n, SCCPlaceholder):
                CFGUtils._append_scc(graph, ordered_nodes, sccs[n.scc_id])
            else:
                ordered_nodes.append(n)

        if nodes is None:
            return ordered_nodes

        nodes = set(nodes)
        ordered_nodes = [ n for n in ordered_nodes if n in nodes ]
        return ordered_nodes

        Sort a given set of nodes from a graph based on the following rules:

        # - if A -> B and not B -> A, then we have A < B
        # - if A -> B and B -> A, then the ordering is undefined

        Following the above rules gives us a quasi-topological sorting of nodes in the graph. It also works for cyclic
        graphs.

        :param networkx.DiGraph graph: A local transition graph of the function.
        :param iterable nodes: A list of nodes to sort. None if you want to sort all nodes inside the graph.
        :return: A list of ordered nodes.
        :rtype: list
        


Following the above rules gives us a quasi-topological sorting of nodes in the graph. It also works for cyclic
graphs.
Following the above rules gives us a quasi - topological sorting of nodes in the graph . It also works for cyclic graphs .
def quasi_topological_sort_nodes(graph, nodes=None):
        if graph.number_of_nodes() == 1:
            return list(graph.nodes())
        graph_copy = networkx.DiGraph()
        sccs = [ scc for scc in networkx.strongly_connected_components(graph) if len(scc) > 1 ]
        for src, dst in graph.edges():
            scc_index = CFGUtils._components_index_node(sccs, src)
            if scc_index is not None:
                src = SCCPlaceholder(scc_index)
            scc_index = CFGUtils._components_index_node(sccs, dst)
            if scc_index is not None:
                dst = SCCPlaceholder(scc_index)
            if isinstance(src, SCCPlaceholder) and isinstance(dst, SCCPlaceholder) and src == dst:
                continue
            if src == dst:
                continue
            graph_copy.add_edge(src, dst)
        out_degree_zero_nodes = [node for (node, degree) in graph.out_degree() if degree == 0]
        for node in out_degree_zero_nodes:
            if graph.in_degree(node) == 0:
                graph_copy.add_node(node)
        tmp_nodes = networkx.topological_sort(graph_copy)
        ordered_nodes = [ ]
        for n in tmp_nodes:
            if isinstance(n, SCCPlaceholder):
                CFGUtils._append_scc(graph, ordered_nodes, sccs[n.scc_id])
            else:
                ordered_nodes.append(n)
        if nodes is None:
            return ordered_nodes
        nodes = set(nodes)
        ordered_nodes = [ n for n in ordered_nodes if n in nodes ]
        return ordered_nodes
def quasi_topological_sort_nodes ( graph , nodes = None ) : if graph . number_of_nodes ( ) == 1 : return list ( graph . nodes ( ) ) graph_copy = networkx . DiGraph ( ) sccs = [ scc for scc in networkx . strongly_connected_components ( graph ) if len ( scc ) > 1 ] for src , dst in graph . edges ( ) : scc_index = CFGUtils . _components_index_node ( sccs , src ) if scc_index is not None : src = SCCPlaceholder ( scc_index ) scc_index = CFGUtils . _components_index_node ( sccs , dst ) if scc_index is not None : dst = SCCPlaceholder ( scc_index ) if isinstance ( src , SCCPlaceholder ) and isinstance ( dst , SCCPlaceholder ) and src == dst : continue if src == dst : continue graph_copy . add_edge ( src , dst ) out_degree_zero_nodes = [ node for ( node , degree ) in graph . out_degree ( ) if degree == 0 ] for node in out_degree_zero_nodes : if graph . in_degree ( node ) == 0 : graph_copy . add_node ( node ) tmp_nodes = networkx . topological_sort ( graph_copy ) ordered_nodes = [ ] for n in tmp_nodes : if isinstance ( n , SCCPlaceholder ) : CFGUtils . _append_scc ( graph , ordered_nodes , sccs [ n . scc_id ] ) else : ordered_nodes . append ( n ) if nodes is None : return ordered_nodes nodes = set ( nodes ) ordered_nodes = [ n for n in ordered_nodes if n in nodes ] return ordered_nodes
Sort a given set of nodes from a graph based on the following rules:
 - if A -> B and not B -> A, then we have A < B
 - if A -> B and B -> A, then the ordering is undefined
Sort a given set of nodes from a graph based on the following rules : - if A - > B and not B - > A then we have A < B - if A - > B and B - > A then the ordering is undefined
"""
        Sort a given set of nodes from a graph based on the following rules:

        # - if A -> B and not B -> A, then we have A < B
        # - if A -> B and B -> A, then the ordering is undefined

        Following the above rules gives us a quasi-topological sorting of nodes in the graph. It also works for cyclic
        graphs.

        :param networkx.DiGraph graph: A local transition graph of the function.
        :param iterable nodes: A list of nodes to sort. None if you want to sort all nodes inside the graph.
        :return: A list of ordered nodes.
        :rtype: list
        """ # fast path for single node graphs # make a copy to the graph since we are gonna modify it # find all strongly connected components in the graph # collapse all strongly connected components # add loners # topological sort on acyclic graph `graph_copy`
A list of ordered nodes.
A list of ordered nodes .
list
graph
A local transition graph of the function.
A local transition graph of the function .
nodes
A list of nodes to sort. None if you want to sort all nodes inside the graph.
A list of nodes to sort . None if you want to sort all nodes inside the graph .