Misc: fix potential ddos when misc.last command is fed a specially-crafted regexp.

This commit is contained in:
Daniel Folkinshteyn 2011-08-12 16:30:46 -04:00
parent 3e0375812a
commit 57884bba57

View File

@ -43,6 +43,7 @@ import supybot.irclib as irclib
import supybot.ircmsgs as ircmsgs import supybot.ircmsgs as ircmsgs
import supybot.ircutils as ircutils import supybot.ircutils as ircutils
import supybot.callbacks as callbacks import supybot.callbacks as callbacks
from supybot import commands
from supybot.utils.iter import ifilter from supybot.utils.iter import ifilter
@ -314,10 +315,27 @@ class Misc(callbacks.Plugin):
predicates.setdefault('without', []).append(f) predicates.setdefault('without', []).append(f)
elif option == 'regexp': elif option == 'regexp':
def f(m, arg=arg): def f(m, arg=arg):
def f1(s, arg):
"""Since we can't enqueue match objects into the multiprocessing queue,
we'll just wrap the function to return bools."""
if arg.search(s) is not None:
return True
else:
return False
if ircmsgs.isAction(m): if ircmsgs.isAction(m):
return arg.search(ircmsgs.unAction(m)) m1 = ircmsgs.unAction(m)
#return arg.search(ircmsgs.unAction(m))
else: else:
return arg.search(m.args[1]) m1 = m.args[1]
#return arg.search(m.args[1])
try:
# use a subprocess here, since specially crafted regexps can
# take exponential time and hang up the bot.
# timeout of 0.1 should be more than enough for any normal regexp.
v = commands.process(f1, m1, arg, timeout=0.1, pn=self.name(), cn='last')
return v
except commands.ProcessTimeoutError:
return False
predicates.setdefault('regexp', []).append(f) predicates.setdefault('regexp', []).append(f)
elif option == 'nolimit': elif option == 'nolimit':
nolimit = True nolimit = True