diff --git a/lib/ansible/module_utils/basic.py b/lib/ansible/module_utils/basic.py index 94326711ba2..15c0f0eef32 100644 --- a/lib/ansible/module_utils/basic.py +++ b/lib/ansible/module_utils/basic.py @@ -101,6 +101,44 @@ except ImportError: import syslog has_journal = False +try: + from ast import literal_eval as _literal_eval +except ImportError: + # a replacement for literal_eval that works with python 2.4. from: + # https://mail.python.org/pipermail/python-list/2009-September/551880.html + # which is essentially a cut/past from an earlier (2.6) version of python's + # ast.py + from compiler import parse + from compiler.ast import * + def _literal_eval(node_or_string): + """ + Safely evaluate an expression node or a string containing a Python + expression. The string or node provided may only consist of the following + Python literal structures: strings, numbers, tuples, lists, dicts, booleans, + and None. + """ + _safe_names = {'None': None, 'True': True, 'False': False} + if isinstance(node_or_string, basestring): + node_or_string = parse(node_or_string, mode='eval') + if isinstance(node_or_string, Expression): + node_or_string = node_or_string.node + def _convert(node): + if isinstance(node, Const) and isinstance(node.value, (basestring, int, float, long, complex)): + return node.value + elif isinstance(node, Tuple): + return tuple(map(_convert, node.nodes)) + elif isinstance(node, List): + return list(map(_convert, node.nodes)) + elif isinstance(node, Dict): + return dict((_convert(k), _convert(v)) for k, v in node.items) + elif isinstance(node, Name): + if node.name in _safe_names: + return _safe_names[node.name] + elif isinstance(node, UnarySub): + return -_convert(node.expr) + raise ValueError('malformed string') + return _convert(node_or_string) + FILE_COMMON_ARGUMENTS=dict( src = dict(), mode = dict(), @@ -655,9 +693,9 @@ class AnsibleModule(object): try: result = None if not locals: - result = eval(str) + result = _literal_eval(str) else: - result = eval(str, None, locals) + result = _literal_eval(str, None, locals) if include_exceptions: return (result, None) else: