Exemple #1
0
def make_fake_object(cls: type, varname: str) -> object:
    constructor = get_smt_proxy_type(cls)
    try:
        proxy = constructor()
    except TypeError as e:
        # likely the type has a __new__ that expects arguments
        raise CrosshairUnsupported(f'Unable to proxy {name_of_type(cls)}: {e}')
    for name, typ in get_type_hints(cls).items():
        origin = getattr(typ, '__origin__', None)
        if origin is Callable:
            continue
        value = proxy_for_type(
            typ, varname + '.' + name + context_statespace().uniq())
        object.__setattr__(proxy, name, value)
    return proxy
Exemple #2
0
def get_smt_proxy_type(cls: type) -> type:
    if issubclass(cls, SmtProxyMarker):
        return cls
    global _SMT_PROXY_TYPES
    cls_name = name_of_type(cls)
    if cls not in _SMT_PROXY_TYPES:
        def symbolic_init(self):
            self.__class__ = cls
        class_body = { '__init__': symbolic_init }
        try:
            proxy_cls = type(cls_name + '_proxy', (SmtProxyMarker, cls), class_body)
        except TypeError as e:
            if 'is not an acceptable base type' in str(e):
                raise CrosshairUnsupported(f'Cannot subclass {cls_name}')
            else:
                raise
        _SMT_PROXY_TYPES[cls] = proxy_cls
    return _SMT_PROXY_TYPES[cls]
Exemple #3
0
 def __exit__(self, exc_type, exc_value, tb):
     if isinstance(exc_value, (PostconditionFailed, IgnoreAttempt)):
         if isinstance(exc_value, PostconditionFailed):
             # Postcondition : although this indicates a problem, it's with a
             # subroutine; not this function.
             # Usualy we want to ignore this because it will be surfaced more locally
             # in the subroutine.
             debug(
                 f'Ignoring based on internal failed post condition: {exc_value}'
             )
         self.ignore = True
         self.analysis = CallAnalysis()
         return True
     if isinstance(exc_value, self.expected_exceptions):
         debug(f'Hit expected exception: {exc_value}')
         self.ignore = True
         self.analysis = CallAnalysis(VerificationStatus.CONFIRMED)
         return True
     if isinstance(exc_value, TypeError):
         exc_str = str(exc_value)
         if ('SmtStr' in exc_str or 'SmtInt' in exc_str
                 or 'SmtFloat' in exc_str
                 or 'expected string or bytes-like object' in exc_str):
             # Ideally we'd attempt literal strings after encountering this.
             # See https://github.com/pschanely/CrossHair/issues/8
             debug('Proxy intolerace at: ', traceback.format_exc())
             raise CrosshairUnsupported('Detected proxy intolerance: ' +
                                        exc_str)
     if isinstance(exc_value,
                   (UnexploredPath, CrosshairInternal, z3.Z3Exception)):
         return False  # internal issue: re-raise
     if isinstance(
             exc_value,
             BaseException):  # TODO: should this be "Exception" instead?
         # Most other issues are assumed to be user-level exceptions:
         self.user_exc = (exc_value,
                          traceback.extract_tb(sys.exc_info()[2]))
         self.analysis = CallAnalysis(VerificationStatus.REFUTED)
         return True  # suppress user-level exception
     return False  # re-raise resource and system issues