safe eval of moderately simple math expressions
Joel Hedlund
joel.hedlund at gmail.com
Thu Apr 9 11:56:49 EDT 2009
Hi all!
I'm writing a program that presents a lot of numbers to the user, and I
want to let the user apply moderately simple arithmentics to these
numbers. One possibility that comes to mind is to use the eval function,
but since that sends up all kinds of warning flags in my head, I thought
I'd put my idea out here first so you guys can tell me if I'm insane. :-)
This is the gist of it:
----------------------------------------------------------
import math
globals = dict((s, getattr(math, s)) for s in dir(math) if '_' not in s)
globals.update(__builtins__=None, divmod=divmod, round=round)
def calc(expr, x):
if '_' in expr:
raise ValueError("expr must not contain '_' characters")
try:
return eval(expr, globals, dict(x=x))
except:
raise ValueError("bad expr or x")
print calc('cos(x*pi)', 1.33)
----------------------------------------------------------
This lets the user do stuff like "exp(-0.01*x)" or "round(100*x)" but
prevents malevolent stuff like "__import__('os').system('del *.*')" or
"(t for t in (42).__class__.__base__.__subclasses__() if t.__name__ ==
'file').next()" from messing things up.
I assume there's lots of nasty and absolutely lethal stuff that I've
missed, and I kindly request you show me the error of my ways.
Thank you for your time!
/Joel Hedlund
More information about the Python-list
mailing list