def test_stdout(self): old_redirect_stdout = settings.REDIRECT_STDOUT settings.REDIRECT_STDOUT = True try: sandbox = Sandbox() sandbox.run('print ("Hello World")') assert sandbox.stdout == "Hello World\n" finally: settings.REDIRECT_STDOUT = old_redirect_stdout
def __init__(self, action_handler, **kwargs): super(ManagedDebugger, self).__init__(**kwargs) self._bdb = Bdb() self._sandbox = Sandbox() self._handler = action_handler self._bdb.user_call = self._bdb_call self._bdb.user_line = self._bdb_line self._bdb.user_return = self._bdb_return self._bdb.user_exception = self._bdb_exception
def test_unsafe_import(self): sandbox = Sandbox() for module_name in pkg_resources.__dict__: if module_name in settings.SAFE_MODULES: continue self.assertRaises(UnsafeImportError, sandbox.run, "import %s" % module_name)
class ManagedDebugger(object): """ Managed Python Debugger """ _wait_stack_height = 0 _done = False _excep_logged = False _script_lines = [] def __init__(self, action_handler, **kwargs): super(ManagedDebugger, self).__init__(**kwargs) self._bdb = Bdb() self._sandbox = Sandbox() self._handler = action_handler self._bdb.user_call = self._bdb_call self._bdb.user_line = self._bdb_line self._bdb.user_return = self._bdb_return self._bdb.user_exception = self._bdb_exception def _initialize(self): self._done = False self._excep_logged = False self._wait_stack_height = 0 # bdb Callbacks def _bdb_call(self, frame, args): if self._done: return # Execution is stopped if frame.f_code.co_filename != "<string>" or frame.f_lineno <= 0: self._wait_stack_height += 1 return if self._wait_stack_height: self._wait_stack_height += 1 return if not self._bdb.stop_here(frame): return script_line = self._get_script_line(frame.f_code.co_firstlineno) if contains_class_defination(script_line): self._wait_stack_height = 1 return args = self._extract_passed_arguments(frame) self.trigger(DebuggerEvent.EnterBlock, frame=frame, arguments=args) def _extract_passed_arguments(self, frame): function = frame.f_globals[frame.f_code.co_name] arg_specs = inspect.getargspec(function) args = {arg: frame.f_locals[arg] for arg in arg_specs.args} if arg_specs.varargs: args[arg_specs.varargs] = frame.f_locals[arg_specs.varargs] if arg_specs.keywords: args[arg_specs.keywords] = frame.f_locals[arg_specs.keywords] return args def _bdb_line(self, frame): if self._done or self._wait_stack_height: return self._excep_logged = False self.trigger(DebuggerEvent.StepLine, frame=frame) def _bdb_return(self, frame, value): if self._done: return if self._wait_stack_height: self._wait_stack_height -= 1 elif frame.f_code.co_filename == "<string>": self.trigger(DebuggerEvent.ExitBlock, frame=frame, return_value=value) def _bdb_exception(self, frame, info): if self._done or self._wait_stack_height: return self._excep_logged = True ex_type, value, tb = info self.trigger(DebuggerEvent.Exception, frame=frame, ex_type=ex_type, value=value, traceback=tb) def trigger(self, event, *args, **kwargs): return self._handler(event, *args, **kwargs) def _get_script_line(self, n): return self.script_lines[n - 1] def get_stack(self, frame, tb): return self._bdb.get_stack(frame, tb) @property def stdout(self): return self._sandbox.stdout def run(self, script, input_queue=None): self._initialize() try: self.script_lines = script.splitlines() self._sandbox.run(script, input_queue, runner=self._bdb.run) except SyntaxError as ex: self.trigger(DebuggerEvent.SyntaxError, exception=ex) except: if not self._excep_logged: logger.exception( "Internal Error in Debugger\n" "Script:\n%s\n" "Input Queue:%s", script, input_queue) ex_type, value, tb = sys.exc_info() self.trigger(DebuggerEvent.SystemError, type=ex_type, value=value, traceback=tb) finally: self._done = True
class ManagedDebugger(object): """ Managed Python Debugger """ _wait_stack_height = 0 _done = False _excep_logged = False _script_lines = [] def __init__(self, action_handler, **kwargs): super(ManagedDebugger, self).__init__(**kwargs) self._bdb = Bdb() self._sandbox = Sandbox() self._handler = action_handler self._bdb.user_call = self._bdb_call self._bdb.user_line = self._bdb_line self._bdb.user_return = self._bdb_return self._bdb.user_exception = self._bdb_exception def _initialize(self): self._done = False self._excep_logged = False self._wait_stack_height = 0 # bdb Callbacks def _bdb_call(self, frame, args): if self._done: return # Execution is stopped if frame.f_code.co_filename != "<string>" or frame.f_lineno <= 0: self._wait_stack_height += 1 return if self._wait_stack_height: self._wait_stack_height += 1 return if not self._bdb.stop_here(frame): return script_line = self._get_script_line(frame.f_code.co_firstlineno) if contains_class_defination(script_line): self._wait_stack_height = 1 return args = self._extract_passed_arguments(frame) self.trigger(DebuggerEvent.EnterBlock, frame=frame, arguments=args) def _extract_passed_arguments(self, frame): function = frame.f_globals[frame.f_code.co_name] arg_specs = inspect.getargspec(function) args = { arg: frame.f_locals[arg] for arg in arg_specs.args } if arg_specs.varargs: args[arg_specs.varargs] = frame.f_locals[arg_specs.varargs] if arg_specs.keywords: args[arg_specs.keywords] = frame.f_locals[arg_specs.keywords] return args def _bdb_line(self, frame): if self._done or self._wait_stack_height: return self._excep_logged = False self.trigger(DebuggerEvent.StepLine, frame=frame) def _bdb_return(self, frame, value): if self._done: return if self._wait_stack_height: self._wait_stack_height -= 1 elif frame.f_code.co_filename == "<string>": self.trigger(DebuggerEvent.ExitBlock, frame=frame, return_value=value) def _bdb_exception(self, frame, info): if self._done or self._wait_stack_height: return self._excep_logged = True ex_type, value, tb = info self.trigger(DebuggerEvent.Exception, frame=frame, ex_type=ex_type, value=value, traceback=tb) def trigger(self, event, *args, **kwargs): return self._handler(event, *args, **kwargs) def _get_script_line(self, n): return self.script_lines[n - 1] def get_stack(self, frame, tb): return self._bdb.get_stack(frame, tb) @property def stdout(self): return self._sandbox.stdout def run(self, script, input_queue=None): self._initialize() try: self.script_lines = script.splitlines() self._sandbox.run(script, input_queue, runner=self._bdb.run) except SyntaxError as ex: self.trigger(DebuggerEvent.SyntaxError, exception=ex) except: if not self._excep_logged: logger.exception( "Internal Error in Debugger\n" "Script:\n%s\n" "Input Queue:%s", script, input_queue ) ex_type, value, tb = sys.exc_info() self.trigger(DebuggerEvent.SystemError, type=ex_type, value=value, traceback=tb) finally: self._done = True
def test_system_exit(self): sandbox = Sandbox() sandbox.run('raise SystemExit()')
def test_safe_import(self): sandbox = Sandbox() for module_name in settings.SAFE_MODULES: sandbox.run("import %s" % module_name)
def test_hello_world(self): sandbox = Sandbox() sandbox.run("print ('Hello Wolrd')")
def test_unsafe_builtins(self): sandbox = Sandbox() for name in settings.UNSAFE_BUILTINS: self.assertRaises(NameError, sandbox.run, name)
def test_safe_import_non_str(self): sandbox = Sandbox() self.assertRaises(TypeError, sandbox.run, "__import__([])")