[pybot-commits] CVS: pybot/pybot/modules eval.py,1.5,1.6
Brought to you by:
niemeyer
From: Gustavo N. <nie...@us...> - 2003-08-29 00:39:03
|
Update of /cvsroot/pybot/pybot/pybot/modules In directory sc8-pr-cvs1:/tmp/cvs-serv29720/pybot/modules Modified Files: eval.py Log Message: * modules/eval.py: Implemented a forking/timeout scheme to protect against DoS evaluations. Now it should be possible to give wider access to the module. Index: eval.py =================================================================== RCS file: /cvsroot/pybot/pybot/pybot/modules/eval.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** eval.py 24 Aug 2003 19:30:53 -0000 1.5 --- eval.py 29 Aug 2003 00:38:56 -0000 1.6 *************** *** 18,22 **** --- 18,26 ---- from pybot.locals import * + import thread + import signal + import time import math + import os HELP = """ *************** *** 38,41 **** --- 42,47 ---- """ + TIMEOUT = 3 + class Eval: def __init__(self): *************** *** 47,69 **** del self.dict["__file__"] del self.dict["__name__"] ! self.dict["map"] = map ! self.dict["zip"] = zip ! self.dict["len"] = len ! self.dict["min"] = min ! self.dict["max"] = max ! self.dict["chr"] = chr ! self.dict["ord"] = ord self.dict["abs"] = abs self.dict["hex"] = hex self.dict["int"] = int ! self.dict["oct"] = oct self.dict["list"] = list self.dict["long"] = long ! self.dict["float"] = float self.dict["round"] = round self.dict["tuple"] = tuple ! self.dict["reduce"] = reduce ! self.dict["filter"] = filter ! self.dict["coerce"] = coerce # Match 'eval <expr>' --- 53,91 ---- del self.dict["__file__"] del self.dict["__name__"] ! self.dict["False"] = False ! self.dict["True"] = True self.dict["abs"] = abs + self.dict["bool"] = bool + self.dict["chr"] = chr + self.dict["cmp"] = cmp + self.dict["coerce"] = coerce + self.dict["complex"] = complex + self.dict["dict"] = dict + self.dict["divmod"] = divmod + self.dict["filter"] = filter + self.dict["float"] = float + self.dict["hash"] = hash self.dict["hex"] = hex + self.dict["id"] = id self.dict["int"] = int ! self.dict["len"] = len self.dict["list"] = list self.dict["long"] = long ! self.dict["map"] = map ! self.dict["max"] = max ! self.dict["min"] = min ! self.dict["oct"] = oct ! self.dict["ord"] = ord ! self.dict["pow"] = pow ! self.dict["range"] = range ! self.dict["reduce"] = reduce ! self.dict["repr"] = repr self.dict["round"] = round + self.dict["str"] = round self.dict["tuple"] = tuple ! self.dict["unichr"] = unichr ! self.dict["unicode"] = unicode ! self.dict["xrange"] = range ! self.dict["zip"] = zip # Match 'eval <expr>' *************** *** 79,83 **** mm.unregister_help(HELP) mm.unregister_perm("eval") ! def message(self, msg): if not msg.forme: --- 101,167 ---- mm.unregister_help(HELP) mm.unregister_perm("eval") ! ! def fork_eval(self, expr): ! try: ! code = compile(expr, "<string>", "eval") ! except: ! return None ! r, w = os.pipe() ! pid = os.fork() ! if pid == 0: ! os.close(r) ! fw = os.fdopen(w, "w") ! try: ! fw.write(str(eval(code, self.dict))) ! except: ! pass ! fw.close() ! os._exit(1) ! os.close(w) ! fr = os.fdopen(r, "r") ! answer = None ! timeout = TIMEOUT ! while 1: ! try: ! _pid, status = os.waitpid(pid, os.WNOHANG) ! except os.error: ! os.kill(pid, signal.SIGKILL) ! time.sleep(0.5) ! try: ! os.waitpid(pid, os.WNOHANG) ! except os.error: ! pass ! break ! if pid == _pid: ! answer = fr.read() ! break ! else: ! timeout -= 1 ! if not timeout: ! answer = ["Couldn't wait for your answer.", ! "Processing your answer took too long.", ! "I'm in a hurry and can't wait for " ! "your answer."] ! os.kill(pid, signal.SIGKILL) ! time.sleep(0.5) ! try: ! os.waitpid(pid, os.WNOHANG) ! except os.error: ! pass ! break ! time.sleep(1) ! return answer ! ! def eval(self, msg, expr): ! answer = self.fork_eval(expr) ! if not answer: ! msg.answer("%:", ["Can't evaluate this", ! "There's something wrong with this " ! "expression"], [".", "!"]) ! elif len(answer) > 255: ! msg.answer("%:", "Your answer is too long", [".", "!"]) ! else: ! msg.answer("%:", answer) ! def message(self, msg): if not msg.forme: *************** *** 87,101 **** if m: if mm.hasperm(msg, "eval"): ! try: ! answer = str(eval(m.group("expr"), self.dict)) ! except: ! msg.answer("%:", ["Can't evaluate this", ! "There's something wrong with this " ! "expression"], [".", "!"]) ! else: ! if len(answer) > 255: ! msg.answer("%:", "Sorry, your answer is too long...") ! else: ! msg.answer("%:", str(answer)) else: msg.answer("%:", ["Sorry...", "Oops!"], --- 171,175 ---- if m: if mm.hasperm(msg, "eval"): ! thread.start_new_thread(self.eval, (msg, m.group("expr"))) else: msg.answer("%:", ["Sorry...", "Oops!"], |