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

Signed-off-by: James McCoy <jamessan@users.sourceforge.net>
This commit is contained in:
Daniel Folkinshteyn 2011-08-12 16:30:46 -04:00 committed by James McCoy
parent 72c5c8ec09
commit 9356d0734f

View File

@ -35,6 +35,7 @@ import time
import supybot import supybot
import supybot.conf as conf import supybot.conf as conf
from supybot import commands
import supybot.utils as utils import supybot.utils as utils
from supybot.commands import * from supybot.commands import *
import supybot.ircdb as ircdb import supybot.ircdb as ircdb
@ -312,10 +313,25 @@ 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):
if ircmsgs.isAction(m): def f1(s, arg):
return arg.search(ircmsgs.unAction(m)) """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: else:
return arg.search(m.args[1]) return False
if ircmsgs.isAction(m):
m1 = ircmsgs.unAction(m)
else:
m1 = 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