def register_patch(entity: object, patch_value: Callable, attr_name: Optional[str] = None): if attr_name in _PATCH_REGISTRATIONS[IdentityWrapper(entity)]: raise CrosshairInternal(f'Doubly registered patch: {object} . {attr_name}') if attr_name is None: attr_name = getattr(patch_value, '__name__', None) assert attr_name is not None _PATCH_REGISTRATIONS[IdentityWrapper(entity)][attr_name] = patch_value
def symbolic_run( self, fn: Callable[[TrackingStateSpace], object] ) -> Tuple[object, Optional[BaseException]]: search_root = SinglePathNode(True) patched_builtins = Patched( {IdentityWrapper(builtins): builtin_patches()}, enabled=lambda: True) with patched_builtins: for itr in range(1, 200): debug('iteration', itr) space = TrackingStateSpace(time.time() + 10.0, 1.0, search_root=search_root) try: return (realize(fn(space)), None) except IgnoreAttempt as e: debug('ignore iteration attempt: ', str(e)) pass except BaseException as e: #traceback.print_exc() return (None, e) top_analysis, space_exhausted = space.bubble_status( CallAnalysis()) if space_exhausted: return ( None, CrosshairInternal(f'exhausted after {itr} iterations')) return (None, CrosshairInternal( 'Unable to find a successful symbolic execution'))
def _unwrap(self, value): if self.is_enforcement_wrapper(value): return self.original_map[IdentityWrapper(value)] elif is_singledispatcher(value): return self._transform_singledispatch(value, self._unwrap) elif isinstance(value, type): self._unwrap_class(value) return value
def _unwrap_class(self, cls: type): for superclass in cls.__mro__: for method_name, method in list(superclass.__dict__.items()): if self.is_enforcement_wrapper(method): setattr( superclass, method_name, self.original_map[IdentityWrapper(method)], )
def get_resolved_signature(fn: Callable) -> inspect.Signature: wrapped = IdentityWrapper(fn) if wrapped not in _RESOLVED_FNS: _RESOLVED_FNS.add(wrapped) try: fn.__annotations__ = get_type_hints(fn) except Exception as e: debug('Could not resolve annotations on', fn, ':', e) return inspect.signature(fn)
def _wrap_fn(self, fn: Callable, conditions: Optional[Conditions] = None) -> Callable: wrapper = self.wrapper_map.get(fn) if wrapper is not None: return wrapper if self.is_enforcement_wrapper(fn): return fn conditions = conditions or get_fn_conditions(fn) if conditions and conditions.has_any(): wrapper = EnforcementWrapper( self.interceptor(fn), conditions, self) functools.update_wrapper(wrapper, fn) else: wrapper = fn self.wrapper_map[fn] = wrapper self.original_map[IdentityWrapper(wrapper)] = fn return wrapper
def _wrap_fn(self, fn: Callable, conditions: Optional[Conditions] = None) -> Callable: wrapper = self.wrapper_map.get(fn) if wrapper is not None: return wrapper if conditions is None: conditions = self.condition_parser.get_fn_conditions( FunctionInfo.from_fn(fn)) # type: ignore if conditions and conditions.has_any(): wrapper = EnforcementWrapper(self.interceptor(fn), conditions, self) functools.update_wrapper(wrapper, fn) else: wrapper = fn self.wrapper_map[fn] = wrapper self.original_map[IdentityWrapper(wrapper)] = fn return wrapper
def _wrap_fn(self, fn: Callable, raw_fn: object = None, conditions: Optional[Conditions] = None) -> Callable: # `raw_fn` is the unresolved descriptor, as appropriate. if raw_fn is None: raw_fn = fn wrapper = self.wrapper_map.get(raw_fn) if wrapper is not None: return wrapper conditions = conditions or self.condition_parser.get_fn_conditions(fn) if conditions and conditions.has_any(): wrapper = EnforcementWrapper(self.interceptor(fn), conditions, self) functools.update_wrapper(wrapper, fn) else: wrapper = fn self.wrapper_map[raw_fn] = wrapper self.original_map[IdentityWrapper(wrapper)] = raw_fn return wrapper
def _wrap_class_members(self, cls: type, class_conditions: ClassConditions) -> None: method_conditions = dict(class_conditions.methods) for method_name, method in list(cls.__dict__.items()): # Note that `method` is post-property resolution. Also grab the raw member: raw_method = cls.__dict__.get(method_name) if raw_method is None: # likely defined on a superclass continue conditions = method_conditions.get(method_name) if conditions is None: continue if isinstance(raw_method, (staticmethod, classmethod)): inner_wrapper = self._wrap_fn(raw_method.__func__, raw_fn=raw_method, conditions=conditions) wrapper: object = type(raw_method)(inner_wrapper) self.original_map[IdentityWrapper(wrapper)] = raw_method else: wrapper = self._wrap_fn(method, raw_fn=raw_method, conditions=conditions) setattr(cls, method_name, wrapper)
def _wrap_class_members(self, cls: type, class_conditions: ClassConditions) -> None: method_conditions = dict(class_conditions.methods) for method_name in list(cls.__dict__.keys()): conditions = method_conditions.get(method_name) if conditions is None: continue ctxfn = FunctionInfo.from_class(cls, method_name) raw_fn = ctxfn.descriptor wrapper = self.wrapper_map.get(raw_fn) if wrapper is None: if conditions.has_any(): fn, _ = ctxfn.callable() wrapper = EnforcementWrapper(self.interceptor(fn), conditions, self) functools.update_wrapper(wrapper, fn) else: wrapper = fn self.wrapper_map[raw_fn] = wrapper outer_wrapper = ctxfn.patch_logic(wrapper) self.original_map[IdentityWrapper(outer_wrapper)] = raw_fn setattr(cls, method_name, outer_wrapper)
def is_enforcement_wrapper(self, value): return IdentityWrapper(value) in self.original_map
def _unwrap_class(self, cls: type): for method_name, method in list(inspect.getmembers(cls, inspect.isfunction)): if self.is_enforcement_wrapper(method): setattr(cls, method_name, self.original_map[IdentityWrapper(method)])
def builtin_patches(): return _PATCH_REGISTRATIONS[IdentityWrapper(builtins)]