<commit_before>import copy
import logging

from .smtlib import solver, Bool
from ..utils.helpers import issymbolic

#import exceptions
from .cpu.abstractcpu import ConcretizeRegister
from .memory import ConcretizeMemory, MemoryException
from ..platforms.platform import *

logger = logging.getLogger(__name__)


class StateException(Exception):
    ''' All state related exceptions '''


class TerminateState(StateException):
    ''' Terminates current state exploration '''

    def __init__(self, message, testcase=False):
        super().__init__(message)
        self.testcase = testcase

class AbandonState(TerminateState):
    ''' Exception returned for abandoned states when
        execution is finished
    '''

    def __init__(self, message='Abandoned state'):
        super().__init__(message)


class Concretize(StateException):
    ''' Base class for all exceptions that trigger the concretization
        of a symbolic expression

        This will fork the state using a pre-set concretization policy
        Optional `setstate` function set the state to the actual concretized value.
        #Fixme Doc.

    '''
    _ValidPolicies = ['MINMAX', 'ALL', 'SAMPLED', 'ONE']

    def __init__(self, message, expression, setstate=None, policy=None, **kwargs):
        if policy is None:
            policy = 'ALL'
        if policy not in self._ValidPolicies:
            raise Exception(f'Policy ({policy}) must be one of: {", ".join(self._ValidPolicies)}')
        self.expression = expression
        self.setstate = setstate
        self.policy = policy
        self.message = f'Concretize: {message} (Policy: {policy})'
        super().__init__(**kwargs)


class ForkState(Concretize):
    ''' Specialized concretization class for Bool expressions.
        It tries True and False as concrete solutions. /

        Note: as setstate is None the concrete value is not written back
        to the state. So the expression could still by symbolic(but constrained)
        in forked states.
    '''

    def __init__(self, message, expression, **kwargs):
        assert isinstance(expression, Bool), 'Need a Bool to fork a state in two states'
        super().__init__(message, expression, policy='ALL', **kwargs)


class State(Eventful):

    '''
    Representation of a unique program state/path.

    :param ConstraintSet constraints: Initial constraints
    :param Platform platform: Initial operating system state
    :ivar dict context: Local context for arbitrary data storage
    '''

    _published_events = {'generate_testcase'}

    def __init__(self, constraints, platform, **kwargs):
        super().__init__(**kwargs)
        self._platform = platform
        self._constraints = constraints
        self._platform.constraints = constraints
        self._input_symbols = list()
        self._child = None
        self._context = dict()
        # 33
        # Events are lost in serialization and fork !!
        self.forward_events_from(platform)

        # FIXME(felipe) This should go into some event callback in a plugin (start_run?)
        self._init_context()

    def __getstate__(self):
        state = super().__getstate__()
        state['platform'] = self._platform
        state['constraints'] = self._constraints
        state['input_symbols'] = self._input_symbols
        state['child'] = self._child
        state['context'] = self._context
        return state

    def __setstate__(self, state):
        super().__setstate__(state)
        self._platform = state['platform']
        self._constraints = state['constraints']
        self._input_symbols = state['input_symbols']
        self._child = state['child']
        self._context = state['context']
        # 33
        # Events are lost in serialization and fork !!
        self.forward_events_from(self._platform)

    # Fixme(felipe) change for with "state.cow_copy() as st_temp":.
    # This need to change. this is the center of ALL the problems. re. CoW
    def __enter__(self):
        assert self._child is None
        self._platform.constraints = None
        new_state = State(self._constraints.__enter__(), self._platform)
        self.platform.constraints = new_state.constraints
        new_state._input_symbols = list(self._input_symbols)
        new_state._context = copy.copy(self._context)

        self.copy_eventful_state(new_state)

        self._child = new_state
        assert new_state.platform.constraints is new_state.constraints

        return new_state

    def __exit__(self, ty, value, traceback):
        self._constraints.__exit__(ty, value, traceback)
        self._child = None
        self.platform.constraints = self.constraints

    def execute(self):
        try:
            result = self._platform.execute()

        # Instead of State importing SymbolicRegisterException and SymbolicMemoryException
        # from cpu/memory shouldn't we import Concretize from linux, cpu, memory ??
        # We are forcing State to have abstractcpu
        except ConcretizeRegister as e:
            expression = self.cpu.read_register(e.reg_name)

            def setstate(state, value):
                state.cpu.write_register(setstate.e.reg_name, value)
            setstate.e = e
            raise Concretize(str(e),
                             expression=expression,
                             setstate=setstate,
                             policy=e.policy)
        except ConcretizeMemory as e:
            expression = self.cpu.read_int(e.address, e.size)

            def setstate(state, value):
                state.cpu.write_int(setstate.e.address, value, e.size)
            setstate.e = e
            raise Concretize(str(e),
                             expression=expression,
                             setstate=setstate,
                             policy=e.policy)
        except MemoryException as e:
            raise TerminateState(str(e), testcase=True)

        # Remove when code gets stable?
        assert self.platform.constraints is self.constraints
        return result

    @property
    def input_symbols(self):
        return self._input_symbols
<commit_msg>Fixed setstate reference before assignment (#1270)<commit_after>import copy
import logging

from .smtlib import solver, Bool
from ..utils.helpers import issymbolic

#import exceptions
from .cpu.abstractcpu import ConcretizeRegister
from .memory import ConcretizeMemory, MemoryException
from ..platforms.platform import *

logger = logging.getLogger(__name__)


class StateException(Exception):
    ''' All state related exceptions '''


class TerminateState(StateException):
    ''' Terminates current state exploration '''

    def __init__(self, message, testcase=False):
        super().__init__(message)
        self.testcase = testcase

class AbandonState(TerminateState):
    ''' Exception returned for abandoned states when
        execution is finished
    '''

    def __init__(self, message='Abandoned state'):
        super().__init__(message)


class Concretize(StateException):
    ''' Base class for all exceptions that trigger the concretization
        of a symbolic expression

        This will fork the state using a pre-set concretization policy
        Optional `setstate` function set the state to the actual concretized value.
        #Fixme Doc.

    '''
    _ValidPolicies = ['MINMAX', 'ALL', 'SAMPLED', 'ONE']

    def __init__(self, message, expression, setstate=None, policy=None, **kwargs):
        if policy is None:
            policy = 'ALL'
        if policy not in self._ValidPolicies:
            raise Exception(f'Policy ({policy}) must be one of: {", ".join(self._ValidPolicies)}')
        self.expression = expression
        self.setstate = setstate
        self.policy = policy
        self.message = f'Concretize: {message} (Policy: {policy})'
        super().__init__(**kwargs)


class ForkState(Concretize):
    ''' Specialized concretization class for Bool expressions.
        It tries True and False as concrete solutions. /

        Note: as setstate is None the concrete value is not written back
        to the state. So the expression could still by symbolic(but constrained)
        in forked states.
    '''

    def __init__(self, message, expression, **kwargs):
        assert isinstance(expression, Bool), 'Need a Bool to fork a state in two states'
        super().__init__(message, expression, policy='ALL', **kwargs)


class State(Eventful):

    '''
    Representation of a unique program state/path.

    :param ConstraintSet constraints: Initial constraints
    :param Platform platform: Initial operating system state
    :ivar dict context: Local context for arbitrary data storage
    '''

    _published_events = {'generate_testcase'}

    def __init__(self, constraints, platform, **kwargs):
        super().__init__(**kwargs)
        self._platform = platform
        self._constraints = constraints
        self._platform.constraints = constraints
        self._input_symbols = list()
        self._child = None
        self._context = dict()
        # 33
        # Events are lost in serialization and fork !!
        self.forward_events_from(platform)

        # FIXME(felipe) This should go into some event callback in a plugin (start_run?)
        self._init_context()

    def __getstate__(self):
        state = super().__getstate__()
        state['platform'] = self._platform
        state['constraints'] = self._constraints
        state['input_symbols'] = self._input_symbols
        state['child'] = self._child
        state['context'] = self._context
        return state

    def __setstate__(self, state):
        super().__setstate__(state)
        self._platform = state['platform']
        self._constraints = state['constraints']
        self._input_symbols = state['input_symbols']
        self._child = state['child']
        self._context = state['context']
        # 33
        # Events are lost in serialization and fork !!
        self.forward_events_from(self._platform)

    # Fixme(felipe) change for with "state.cow_copy() as st_temp":.
    # This need to change. this is the center of ALL the problems. re. CoW
    def __enter__(self):
        assert self._child is None
        self._platform.constraints = None
        new_state = State(self._constraints.__enter__(), self._platform)
        self.platform.constraints = new_state.constraints
        new_state._input_symbols = list(self._input_symbols)
        new_state._context = copy.copy(self._context)

        self.copy_eventful_state(new_state)

        self._child = new_state
        assert new_state.platform.constraints is new_state.constraints

        return new_state

    def __exit__(self, ty, value, traceback):
        self._constraints.__exit__(ty, value, traceback)
        self._child = None
        self.platform.constraints = self.constraints

    def execute(self):
        try:
            result = self._platform.execute()

        # Instead of State importing SymbolicRegisterException and SymbolicMemoryException
        # from cpu/memory shouldn't we import Concretize from linux, cpu, memory ??
        # We are forcing State to have abstractcpu
        except ConcretizeRegister as e:
            expression = self.cpu.read_register(e.reg_name)

            def setstate(state, value):
                state.cpu.write_register(setstate.e.reg_name, value)
            setstate.e = e
            raise Concretize(str(e),
                             expression=expression,
                             setstate=setstate,
                             policy=e.policy)
        except ConcretizeMemory as e:
            expression = self.cpu.read_int(e.address, e.size)

            def setstate(state, value):
                state.cpu.write_int(setstate.e.address, value, setstate.e.size)
            setstate.e = e
            raise Concretize(str(e),
                             expression=expression,
                             setstate=setstate,
                             policy=e.policy)
        except MemoryException as e:
            raise TerminateState(str(e), testcase=True)

        # Remove when code gets stable?
        assert self.platform.constraints is self.constraints
        return result

    @property
    def input_symbols(self):
        return self._input_symbols

{'fraction_non_alphanumeric': 0.0873170731707317, 'fraction_numerical': 0.000975609756097561, 'mean_word_length': 2.521614657887203, 'pattern_counts': {'":': 2, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6238775', 'n_tokens_mistral': 3234, 'n_tokens_neox': 3153, 'n_words': 941}