eval(expr_str [, globals [, locals]] )
Evaluates the Python expression contained in expr_str. Although this can be a way to write more compact code, it’s potentially dangerous if you evaluate arbitrary input strings input by the user, unless the app is for your own use only.
The following example evaluates a Python expression and returns the result.
>>> a = 100
>>> eval('3 * a +55')
355
The string must contain an expression and not a statement. Therefore, assignment statements cannot be used. However, expressions can contain function calls, and function calls, in turn, can execute statements.
One way to reduce the dangers of eval is to prevent access to symbols. The globals argument, by default, gives the setting for local symbols as well. Setting this argument to an empty dictionary prevents access to symbols. (But note that built-in functions are always accessible.)
>>> eval('3 * 10 +55', {}) # This is fine.
355
>>> eval('3 * a + 55', {}) # ERROR; 'a' no longer defined
One way to bulletproof your code is to create a dictionary containing the symbols you want to be accessible; then give that dictionary as the globals argument:
>>> from math import *
>>> a = 25
>>> dict_1 = {'tan': tan, 'radians': radians, 'a': a }
>>> eval('1000 * tan(radians(a))', dict_1)
176.326980708465
The effect is to create a dictionary that restricts the eval statement to recognize only two functions (tan and radians) and one variable (a).
The locals argument isn’t used much, but you can use it to restrict access to local symbols only. In that case, it won’t usually permit access to functions.
eval('a * a + 100', {}, locals())
Although you can use the arguments to try to make eval safer, you can never fully bulletproof this usage if your application should happen to take an arbitrary string from the user and evaluate it. There are ways hackers can take advantage of such code to bring down a system. So again, take care.
No comments:
Post a Comment