Eval vs Ast.literal_eval: what are the differences?

Asked

Viewed 523 times

8

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

  • Are the functions equivalent? Everything one does to another also does?
  • In security matters, there is priority in using one or the other?
  • What are the real differences between the two functions?

2 answers

11


The two functions compile the code, but 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.

Already the eval allows the string to contain any expression, therefore allows it to execute any type of code, since in python any code can be rewritten in expression form.

On the question of security it is obvious that the literal_eval is safer, because with the eval can do anything that the process running python is allowed to do.

Even so, neither the literal_eval can be recommended to interpret user-provided strings, as a malicious user can create a sufficiently complex string that even the literal_eval can cause a crash python interpreter at the time of compilation.

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

0

This is not really an answer but an opinion (politically incorrect).

Exchange formats

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

parser : STR -> objectoPythonEspecífico

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

Ast.literal_eval

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

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

For example, it does not allow expressions containing: (1) variables and functions, (2) indexing of tuples, lists, dictionaries.

The ast.literal_eval is non-reflective.

val

The eval(expressão), exec(strcodigo), are much more powerful: allows all the 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 the bash, with any powerful tool. Of course, miracles can also be performed.

The eval(str) has to be used carefully when the str has origins uncontrolled and potentially adverse. If the str is somehow 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 it never kept anyone awake. If we do something analogous with a web application: ... it will go wrong!

I see no harm in indiscriminately using Eval 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 else!

  • 1

    Yes, the famous REPL (Read Eval Print Loop)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.