diff --git a/sandbox/Debug.py b/sandbox/Debug.py index 746c6b1f4..ac3360988 100644 --- a/sandbox/Debug.py +++ b/sandbox/Debug.py @@ -65,7 +65,45 @@ def getTracer(fd): class Debug(privmsgs.CapabilityCheckingPrivmsg): capability = 'owner' - def eval(self, irc, msg, args, text): + def __init__(self): + # Setup exec command. + setattr(self.__class__, 'exec', self.__class__._exec) + privmsgs.CapabilityCheckingPrivmsg.__init__(self) + + _evalEnv = {'_': None, + '__': None, + '___': None, + } + _evalEnv.update(globals()) + def eval(self, irc, msg, args, s): + """ + + Evaluates (which should be a Python expression) and + returns its value. If an exception is raised, reports the + exception (and logs the traceback to the bot's logfile). + """ + try: + self._evalEnv.update(locals()) + x = eval(s, self._evalEnv, self._evalEnv) + self._evalEnv['___'] = self._evalEnv['__'] + self._evalEnv['__'] = self._evalEnv['_'] + self._evalEnv['_'] = x + irc.reply(repr(x)) + except SyntaxError, e: + irc.reply('%s: %s' % (utils.exnToString(e), + utils.quoted(s))) + eval = wrap(eval, ['text']) + + def _exec(self, irc, msg, args, s): + """ + + Execs . Returns success if it didn't raise any exceptions. + """ + exec s + irc.replySuccess() + _exec = wrap(_exec, ['text']) + + def simpleeval(self, irc, msg, args, text): """ Evaluates the given expression. @@ -74,7 +112,7 @@ class Debug(privmsgs.CapabilityCheckingPrivmsg): irc.reply(repr(eval(text))) except Exception, e: irc.reply(utils.exnToString(e)) - eval = wrap(eval, ['text']) + simpleeval = wrap(simpleeval, ['text']) def exn(self, irc, msg, args, name): """ diff --git a/scripts/supybot b/scripts/supybot index ecb67bd86..d3a97bc04 100755 --- a/scripts/supybot +++ b/scripts/supybot @@ -152,10 +152,6 @@ if __name__ == '__main__': dest='daemon', help='Determines whether the bot will daemonize. ' 'This is a no-op on non-POSIX systems.') - parser.add_option('', '--allow-eval', action='store_true', - dest='allowEval', - help='Determines whether the bot will ' - 'allow the evaluation of arbitrary Python code.') parser.add_option('', '--allow-default-owner', action='store_true', dest='allowDefaultOwner', help='Determines whether the bot will allow its ' @@ -314,7 +310,6 @@ if __name__ == '__main__': except EnvironmentError, e: log.error('Error opening pid file %s: %s', pidFile, e) - conf.allowEval = options.allowEval conf.allowDefaultOwner = options.allowDefaultOwner if not os.path.exists(conf.supybot.directories.log()): diff --git a/src/Owner.py b/src/Owner.py index c769c87f0..31a13c982 100644 --- a/src/Owner.py +++ b/src/Owner.py @@ -236,8 +236,6 @@ class Owner(privmsgs.CapabilityCheckingPrivmsg): self.log = LogProxy(self.log) # Setup command flood detection. self.commands = ircutils.FloodQueue(60) - # Setup exec command. - setattr(self.__class__, 'exec', self.__class__._exec) # Setup Irc objects, connected to networks. If world.ircs is already # populated, chances are that we're being reloaded, so don't do this. if not world.ircs: @@ -377,66 +375,6 @@ class Owner(privmsgs.CapabilityCheckingPrivmsg): except SyntaxError, e: irc.queueMsg(callbacks.error(msg, str(e))) - if conf.allowEval: - _evalEnv = {'_': None, - '__': None, - '___': None, - } - _evalEnv.update(globals()) - def eval(self, irc, msg, args, s): - """ - - Evaluates (which should be a Python expression) and - returns its value. If an exception is raised, reports the - exception (and logs the traceback to the bot's logfile). - """ - if conf.allowEval: - try: - self._evalEnv.update(locals()) - x = eval(s, self._evalEnv, self._evalEnv) - self._evalEnv['___'] = self._evalEnv['__'] - self._evalEnv['__'] = self._evalEnv['_'] - self._evalEnv['_'] = x - irc.reply(repr(x)) - except SyntaxError, e: - irc.reply('%s: %s' % (utils.exnToString(e), - utils.quoted(s))) - except Exception, e: - self.log.exception('Uncaught exception in Owner.eval.\n' - 'This is not a bug. Please do not ' - 'report it.') - irc.reply(utils.exnToString(e)) - else: - # There's a potential that allowEval got changed after we were - # loaded. Let's be extra-special-safe. - irc.error('You must run Supybot with the --allow-eval ' - 'option for this command to be enabled.') - eval = wrap(eval, ['text']) - - def _exec(self, irc, msg, args, s): - """ - - Execs . Returns success if it didn't raise any exceptions. - """ - if conf.allowEval: - try: - exec s - irc.replySuccess() - except Exception, e: - irc.reply(utils.exnToString(e)) - else: - # There's a potential that allowEval got changed after we were - # loaded. Let's be extra-special-safe. - irc.error('You must run Supybot with the --allow-eval ' - 'option for this command to be enabled.') - _exec = wrap(_exec, ['text']) - else: - def eval(self, irc, msg, args): - """Run your bot with --allow-eval if you want this to work.""" - irc.error('You must give your bot the --allow-eval option for ' - 'this command to be enabled.') - _exec = eval - def announce(self, irc, msg, args, text): """ diff --git a/src/conf.py b/src/conf.py index 00be0949f..1c4638ca5 100644 --- a/src/conf.py +++ b/src/conf.py @@ -64,13 +64,6 @@ version = '0.80.0pre3' ### daemonized = False -### -# allowEval: True if the owner (and only the owner) should be able to eval -# arbitrary Python code. This is specifically *not* a registry -# variable because it shouldn't be modifiable in the bot. -### -allowEval = False - ### # allowDefaultOwner: True if supybot.capabilities is allowed not to include # '-owner' -- that is, if all users should be automatically diff --git a/test/test_Owner.py b/test/test_Owner.py index 6848ffc48..c920aa189 100644 --- a/test/test_Owner.py +++ b/test/test_Owner.py @@ -37,34 +37,9 @@ class OwnerTestCase(PluginTestCase, PluginDocumentation): def testHelpLog(self): self.assertHelp('help log') - def testEval(self): - try: - originalConfAllowEval = conf.allowEval - conf.allowEval = True - self.assertNotError('eval 100') - s = "[irc.__class__ for irc in " \ - "irc.getCallback('Relay').ircstates.keys()]" - self.assertNotRegexp('eval ' + s, '^SyntaxError') - conf.allowEval = False - self.assertError('eval 100') - finally: - conf.allowEval = originalConfAllowEval - def testSrcAmbiguity(self): self.assertError('addcapability foo bar') - def testExec(self): - try: - originalConfAllowEval = conf.allowEval - conf.allowEval = True - self.assertNotError('exec conf.foo = True') - self.failUnless(conf.foo) - del conf.foo - conf.allowEval = False - self.assertError('exec conf.foo = True') - finally: - conf.allowEval = originalConfAllowEval - def testIrcquote(self): self.assertResponse('ircquote PRIVMSG %s :foo' % self.irc.nick, 'foo')