Yet another attempt at a safe eval() call
matt.newville at gmail.com
matt.newville at gmail.com
Sat Jan 5 11:40:34 EST 2013
On Saturday, January 5, 2013 8:17:16 AM UTC-8, Oscar Benjamin wrote:
> On 5 January 2013 16:01, Chris Angelico <rosuav at gmail.com> wrote:
>
> > On Sun, Jan 6, 2013 at 2:56 AM, Oscar Benjamin
>
> > <oscar.j.benjamin at gmail.com> wrote:
>
> >> On 4 January 2013 15:53, Grant Edwards <invalid at invalid.invalid> wrote:
>
> >>> On 2013-01-04, Steven D'Aprano <steve+comp.lang.python at pearwood.info> wrote:
>
> >>>> On Thu, 03 Jan 2013 23:25:51 +0000, Grant Edwards wrote:
>
> >>>>
>
> >>>> * But frankly, you should avoid eval, and write your own mini-integer
>
> >>>> arithmetic evaluator which avoids even the most remote possibility
>
> >>>> of exploit.
>
> >>>
>
> >>> That's obviously the "right" thing to do. I suppose I should figure
>
> >>> out how to use the ast module.
>
> >>
>
> >> Someone has already created a module that does this called numexpr. Is
>
> >> there some reason why you don't want to use that?
>
> >>
>
> >>>>> import numexpr
>
> >>>>> numexpr.evaluate('2+4*5')
>
> >> array(22, dtype=int32)
>
> >>>>> numexpr.evaluate('2+a*5', {'a':4})
>
> >> array(22L)
>
> >
>
> > Is that from PyPI? It's not in my Python 3.3 installation. Obvious
>
> > reason not to use it: Unaware of it. :)
>
>
>
> My apologies. I should have at least provided a link:
>
> http://code.google.com/p/numexpr/
>
>
>
> I installed it from the ubuntu repo under the name python-numexpr. It
>
> is also on PyPI:
>
> http://pypi.python.org/pypi/numexpr
>
>
>
> numexpr is a well established project intended primarily for memory
>
> and cache efficient computations over large arrays of data. Possibly
>
> as a side effect, it can also be used to evaluate simple algebraic
>
> expressions involving ordinary scalar variables.
>
>
>
>
>
> Oscar
The asteval module http://pypi.python.org/pypi/asteval/0.9 and
http://newville.github.com/asteval/ might be another alternative. It's not as fast as numexpr, but a bit more general. It uses the ast module to "compile" an expression into the AST, then walks through that, intercepting Name nodes and using a flat namespace of variables. It disallows imports and does not support all python constructs, but it is a fairly complete in supporting python syntax.
It makes no claim at actually being safe from malicious attack, but should be safer than a straight eval(), and prevent accidental problems when evaluating user-input as code. If anyone can find exploits within it, I'd be happy to try to fix them.
--Matt
More information about the Python-list
mailing list