948
def safe_eval(str, locals=None, include_exceptions=False):
949
def safe_eval(expr, locals={}, include_exceptions=False):
950
951
this is intended for allowing things like:
951
952
with_items: a_list_variable
952
953
where Jinja2 would return a string
953
954
but we do not want to allow it to call functions (outside of Jinja2, where
954
955
the env is constrained)
958
http://stackoverflow.com/questions/12523516/using-ast-and-whitelists-to-make-pythons-eval-safe
956
# FIXME: is there a more native way to do this?
959
return not var.startswith("$") and not '{{' in var
962
return var.startswith("$") or '{{' in var
964
# do not allow method calls to modules
965
if not isinstance(str, basestring):
961
# this is the whitelist of AST nodes we are going to
962
# allow in the evaluation. Any node type other than
963
# those listed here will raise an exception in our custom
964
# visitor class defined below.
986
# AST node types were expanded after 2.6
987
if not sys.version.startswith('2.6'):
994
# builtin functions that are not safe to call
996
'classmethod', 'compile', 'delattr', 'eval', 'execfile', 'file',
997
'filter', 'help', 'input', 'object', 'open', 'raw_input', 'reduce',
998
'reload', 'repr', 'setattr', 'staticmethod', 'super', 'type',
1001
class CleansingNodeVisitor(ast.NodeVisitor):
1002
def generic_visit(self, node):
1003
if type(node) not in SAFE_NODES:
1004
#raise Exception("invalid expression (%s) type=%s" % (expr, type(node)))
1005
raise Exception("invalid expression (%s)" % expr)
1006
super(CleansingNodeVisitor, self).generic_visit(node)
1007
def visit_Call(self, call):
1008
if call.func.id in INVALID_CALLS:
1009
raise Exception("invalid function: %s" % call.func.id)
1011
if not isinstance(expr, basestring):
966
1012
# already templated to a datastructure, perhaps?
967
1013
if include_exceptions:
970
if re.search(r'\w\.\w+\(', str):
971
if include_exceptions:
974
# do not allow imports
975
if re.search(r'import \w+', str):
976
if include_exceptions:
984
result = eval(str, None, locals)
1018
parsed_tree = ast.parse(expr, mode='eval')
1019
cnv = CleansingNodeVisitor()
1020
cnv.visit(parsed_tree)
1021
compiled = compile(parsed_tree, expr, 'eval')
1022
result = eval(compiled, {}, locals)
985
1024
if include_exceptions:
986
1025
return (result, None)
1028
except SyntaxError, e:
1029
# special handling for syntax errors, we just return
1030
# the expression string back as-is
1031
if include_exceptions:
989
1034
except Exception, e:
990
1035
if include_exceptions:
995
1040
def listify_lookup_plugin_terms(terms, basedir, inject):