Merge pull request #1159 from jacksonmj/math

Prevent untrusted users from freezing the bot with Math.rpn, and allow factorial calculation for smaller numbers
This commit is contained in:
Valentin Lorentz 2015-08-29 08:09:12 +02:00
commit 8033e6ae14
2 changed files with 12 additions and 7 deletions

View File

@ -110,13 +110,18 @@ class Math(callbacks.Plugin):
return math.sqrt(x) return math.sqrt(x)
def _cbrt(x): def _cbrt(x):
return math.pow(x, 1.0/3) return math.pow(x, 1.0/3)
def _factorial(x):
if x<=10000:
return math.factorial(x)
else:
raise Exception('factorial argument too large')
_mathEnv['sqrt'] = _sqrt _mathEnv['sqrt'] = _sqrt
_mathEnv['cbrt'] = _cbrt _mathEnv['cbrt'] = _cbrt
_mathEnv['abs'] = abs _mathEnv['abs'] = abs
_mathEnv['max'] = max _mathEnv['max'] = max
_mathEnv['min'] = min _mathEnv['min'] = min
_mathSafeEnv = dict([(x,y) for x,y in _mathEnv.items() _mathSafeEnv = dict([(x,y) for x,y in _mathEnv.items()])
if x not in ['factorial']]) _mathSafeEnv['factorial'] = _factorial
_mathRe = re.compile(r'((?:(?<![A-Fa-f\d)])-)?' _mathRe = re.compile(r'((?:(?<![A-Fa-f\d)])-)?'
r'(?:0x[A-Fa-f\d]+|' r'(?:0x[A-Fa-f\d]+|'
r'0[0-7]+|' r'0[0-7]+|'
@ -279,8 +284,8 @@ class Math(callbacks.Plugin):
x = abs(x) x = abs(x)
stack.append(x) stack.append(x)
except ValueError: # Not a float. except ValueError: # Not a float.
if arg in self._mathEnv: if arg in self._mathSafeEnv:
f = self._mathEnv[arg] f = self._mathSafeEnv[arg]
if callable(f): if callable(f):
called = False called = False
arguments = [] arguments = []
@ -303,7 +308,7 @@ class Math(callbacks.Plugin):
arg1 = stack.pop() arg1 = stack.pop()
s = '%s%s%s' % (arg1, arg, arg2) s = '%s%s%s' % (arg1, arg, arg2)
try: try:
stack.append(eval(s, self._mathEnv, self._mathEnv)) stack.append(eval(s, self._mathSafeEnv, self._mathSafeEnv))
except SyntaxError: except SyntaxError:
irc.error(format(_('%q is not a defined function.'), irc.error(format(_('%q is not a defined function.'),
arg)) arg))

View File

@ -114,7 +114,7 @@ class MathTestCase(PluginTestCase):
self.assertNotError('calc (1600 * 1200) - 2*(1024*1280)') self.assertNotError('calc (1600 * 1200) - 2*(1024*1280)')
self.assertNotError('calc 3-2*4') self.assertNotError('calc 3-2*4')
self.assertNotError('calc (1600 * 1200)-2*(1024*1280)') self.assertNotError('calc (1600 * 1200)-2*(1024*1280)')
self.assertError('calc factorial(99)') self.assertError('calc factorial(20000)')
def testCalcNoNameError(self): def testCalcNoNameError(self):
self.assertNotRegexp('calc foobar(x)', 'NameError') self.assertNotRegexp('calc foobar(x)', 'NameError')
@ -139,7 +139,7 @@ class MathTestCase(PluginTestCase):
self.assertResponse('icalc 1^1', '0') self.assertResponse('icalc 1^1', '0')
self.assertResponse('icalc 10**24', '1' + '0'*24) self.assertResponse('icalc 10**24', '1' + '0'*24)
self.assertRegexp('icalc 49/6', '8.16') self.assertRegexp('icalc 49/6', '8.16')
self.assertNotError('icalc factorial(99)') self.assertNotError('icalc factorial(20000)')
def testRpn(self): def testRpn(self):
self.assertResponse('rpn 5 2 +', '7') self.assertResponse('rpn 5 2 +', '7')