String2List: odd function

Fredrik Lundh fredrik at pythonware.com
Wed Jul 28 18:17:58 EDT 1999


Greg Ewing <greg.ewing at compaq.com> wrote:
> > However, I suspect that this use is not among the common uses for
> > which exec and eval were designed.
> 
> Using eval for something like this is probably overkill.
> Eval and exec will accept *any* valid Python expression
> or statement, respectively - which can do some nasty
> things to the internals of your program if you're not
> careful what you feed into them!

well, last time I checked, eval didn't accept statements.
and you can pass in your own dictionary, to prevent the
expression from being evaluated in the current name-
space.

but that's not enough; consider this:

    >>> d = {}
    >>> eval("__import__('os').remove('precious-file')", d)
   OSError: No such file or directory: 'precious-file'
    >>> print d
    {'__builtins__': {...lots of stuff...}}

here, the __import__ builtin is another way of spelling
"import" (that function is used by the import state-
ment to do the actual work...).  and if you can access
arbitrary modules via eval, there's no limit to what you
can do...

but there's a way around this:

if you look in the dictionary, you'll find that python
automatically inserts an entry called "__builtins__"
which contains the current set of builtin functions
etc.

now, what happens if you add such an entry your-
self, before calling eval.  let's try this:

    >>> d = {"__builtins__": {}}
    >>> eval("__import__('os').remove('precious-file')", d)
    NameError: __import__
    >>> print d
    {"__builtins__": {}}

much better!

to sum this up: if you need to parse arbitrary python
expressions, and you're not 100% sure you can trust
the source, you can use:

    v = eval(s, {"__builtins__": {}})

(which, of course, was what I suggested in my original
reply to isidor...)

</F>





More information about the Python-list mailing list