<commit_before>from collections import defaultdict
import logging

import networkx
import simuvex
import claripy

from ..entry_wrapper import EntryWrapper, CallStack
from .cfg_base import CFGBase
from ..analysis import Analysis
from ..errors import AngrVFGError, AngrVFGRestartAnalysisNotice, AngrError

l = logging.getLogger(name="angr.analyses.vfg")

# The maximum tracing times of a basic block before we widen the results
MAX_ANALYSIS_TIMES_WITHOUT_MERGING = 10
MAX_ANALYSIS_TIMES = 20

class VFGNode(object):
    def __init__(self, addr, key, state=None):
        self.key = key
        self.addr = addr
        self.state = None
        self.widened_state = None
        self.narrowing_times = 0
        self.all_states  = [ ]
        self.events = [ ]
        self.input_variables = [ ]
        self.actions = [ ]

        if state:
            self.all_states.append(state)
            self.state = state

    def __hash__(self):
        return hash(self.key)

    def __repr__(self):
        s = "VFGNode[0x%x] <%s>" % (self.addr, ", ".join([ (("0x%x" % k) if k else "None") for k in self.key ]))
        return s

    def append_state(self, s, is_widened_state=False):
        """
        Appended a new state to this VFGNode.
        :param s: The new state to append
        :param is_widened_state: Whether it is a widened state or not.
        """

        if not is_widened_state:
            self.all_states.append(s)
            self.state = s

        else:
            self.widened_state = s

class VFG(Analysis):
    '''
    This class represents a control-flow graph with static analysis result.
    '''

    def __init__(self, cfg=None, context_sensitivity_level=2, function_start=None, interfunction_level=0, initial_state=None, avoid_runs=None):
        '''

        :param project: The project object.
        :param context_sensitivity_level: The level of context-sensitivity of this VFG.
                                        It ranges from 0 to infinity.
        :return:
        '''

        # Related CFG.
        # We can still perform analysis if you don't specify a CFG. But providing a CFG may give you better result.
        self._cfg = cfg

        # Where to start the analysis
        self._start = function_start

        # Other parameters
        self._avoid_runs = [ ] if avoid_runs is None else avoid_runs
        self._context_sensitivity_level = context_sensitivity_level
        self._interfunction_level = interfunction_level

        # Containers
        self.graph = None # TODO: Maybe we want to remove this line?
        self._graph = None # TODO: Maybe we want to remove this line?
        self._nodes = None

        self._project = self._p

        self._normal_states = { } # Last available state for each program point without widening
        self._widened_states = { } # States on which widening has occurred

        # Initial states for start analyzing different functions
        # It maps function key to its states
        self._function_initial_states = defaultdict(dict)

        # All final states are put in this list
        self.final_states = [ ]

        self._uninitialized_access = { }
        self._state_initialization_map = defaultdict(list)

        self._state_ignored_variables = { }

        # Begin VFG construction!
        self._construct(initial_state=initial_state)

        self.result = {
            "graph": self.graph,
            "final_states": self.final_states
        }
<commit_msg>Re-enabled VFG.result['graph']<commit_after>from collections import defaultdict
import logging

import networkx
import simuvex
import claripy

from ..entry_wrapper import EntryWrapper, CallStack
from .cfg_base import CFGBase
from ..analysis import Analysis
from ..errors import AngrVFGError, AngrVFGRestartAnalysisNotice, AngrError

l = logging.getLogger(name="angr.analyses.vfg")

# The maximum tracing times of a basic block before we widen the results
MAX_ANALYSIS_TIMES_WITHOUT_MERGING = 10
MAX_ANALYSIS_TIMES = 20

class VFGNode(object):
    def __init__(self, addr, key, state=None):
        self.key = key
        self.addr = addr
        self.state = None
        self.widened_state = None
        self.narrowing_times = 0
        self.all_states  = [ ]
        self.events = [ ]
        self.input_variables = [ ]
        self.actions = [ ]

        if state:
            self.all_states.append(state)
            self.state = state

    def __hash__(self):
        return hash(self.key)

    def __repr__(self):
        s = "VFGNode[0x%x] <%s>" % (self.addr, ", ".join([ (("0x%x" % k) if k else "None") for k in self.key ]))
        return s

    def append_state(self, s, is_widened_state=False):
        """
        Appended a new state to this VFGNode.
        :param s: The new state to append
        :param is_widened_state: Whether it is a widened state or not.
        """

        if not is_widened_state:
            self.all_states.append(s)
            self.state = s

        else:
            self.widened_state = s

class VFG(Analysis):
    '''
    This class represents a control-flow graph with static analysis result.
    '''

    def __init__(self, cfg=None, context_sensitivity_level=2, function_start=None, interfunction_level=0, initial_state=None, avoid_runs=None):
        '''

        :param project: The project object.
        :param context_sensitivity_level: The level of context-sensitivity of this VFG.
                                        It ranges from 0 to infinity.
        :return:
        '''

        # Related CFG.
        # We can still perform analysis if you don't specify a CFG. But providing a CFG may give you better result.
        self._cfg = cfg

        # Where to start the analysis
        self._start = function_start

        # Other parameters
        self._avoid_runs = [ ] if avoid_runs is None else avoid_runs
        self._context_sensitivity_level = context_sensitivity_level
        self._interfunction_level = interfunction_level

        # Containers
        self._graph = None # TODO: Maybe we want to remove this line?
        self._nodes = None

        self._project = self._p

        self._normal_states = { } # Last available state for each program point without widening
        self._widened_states = { } # States on which widening has occurred

        # Initial states for start analyzing different functions
        # It maps function key to its states
        self._function_initial_states = defaultdict(dict)

        # All final states are put in this list
        self.final_states = [ ]

        self._uninitialized_access = { }
        self._state_initialization_map = defaultdict(list)

        self._state_ignored_variables = { }

        # Begin VFG construction!
        self._construct(initial_state=initial_state)

        self.result = {
            "graph": self._graph,
            "final_states": self.final_states
        }

{'fraction_non_alphanumeric': 0.0777472129723469, 'fraction_numerical': 0.0028956131460836834, 'mean_word_length': 2.319557904853436, 'pattern_counts': {'":': 4, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3907090', 'n_tokens_mistral': 2021, 'n_tokens_neox': 1921, 'n_words': 593}