[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!"],
|