eval vs ast.literal_eval: what are the differences?

7

In Python it's common to read that ast.literal_eval is an alternative to eval .

  • Are the functions equivalent? What does one do to another also?
  • In security issues, is there priority in using one or the other?
  • What are the real differences between the two functions?
asked by anonymous 03.09.2018 / 14:37

2 answers

10

The two functions compile the code, however ast.literal_eval only executes the code if it is a literal of a basic object: strings, bytes, numbers, True , False and None .

In addition, tuples, lists, dictionaries and sets are accepted as long as they contain only the objects mentioned above.

In the security question, it is obvious that eval is safer because with literal_eval you can do anything that the python-running process has permission to do.

Even though eval can not be recommended to interpret user-supplied strings, a malicious user can create a sufficiently complex string that even literal_eval can cause crash in python interpreter at compile time.

The viable alternative is to use a parsable format such as literal_eval or xml that have safer parsers.

    
03.09.2018 / 18:33
0

This is not quite a response but a (politically incorrect) opinion.

Interchange formats

Both json modules, yaml, xml, ... contain functions that recognize the respective formats (languages) and create a semantic representation

parser : STR -> objectoPythonEspecífico

and serialize prittyprint : objectoPythonEspecífico -> STR being typically used for structured exchange structured between different contexts (different sessions, processes, languages, machines, platforms).

ast.literal_eval

The ast.literal_eval is somewhat similar in that the format is a small subset of the Python language including

  • constants (str, numbers, tuples, lists, dictionaries)
  • You can use a set of "peaceful" operators.

Does not allow for example expressions containing: (1) variables and functions, (2) Indexing of tuples, lists, dictionaries.

The ast.literal_eval is nonreflective.

eval

The eval(expressão) , exec(strcodigo) , are much more powerful: allows all syntax of Python expressions, allow reflexivity: we can access and define new variables, functions, etc.

(in) Security

Fortunately you can do dangerous things with eval , with Python, with system() , with bash , with any powerful tool. Of course miracles can also be performed.

The eval(str) has to be used with caution when str has origins uncontrolled and potentially adverse. If str is in some way dependent on user interaction, the situation is as dangerous as the user is dangerous.

eval(rawinput()) is precisely what we are running when we run the Python interpreter - and this never put anyone to sleep. If we do something analogous to a web application: ... it will go wrong!

I see no harm in using eval indiscriminately in my activities. I defined a calculator that, like the Python interpreter, uses something

print(pp(eval(retoca(rawinput("?"))))

and that allows me fantastic things and also format the disk and everything!

    
05.09.2018 / 10:58