diff --git a/src/utils/gen.py b/src/utils/gen.py index b978bab52..b82976395 100644 --- a/src/utils/gen.py +++ b/src/utils/gen.py @@ -30,9 +30,9 @@ import os import sys +import ast import time import types -import compiler import textwrap import traceback import collections @@ -40,7 +40,6 @@ from itertools import imap from str import format from file import mktemp -from iter import all import crypt @@ -150,32 +149,36 @@ def saltHash(password, salt=None, hash='sha'): hasher = crypt.md5 return '|'.join([salt, hasher((salt + password).encode('utf8')).hexdigest()]) +_astStr2 = ast.Str if sys.version_info[0] < 3 else ast.Bytes def safeEval(s, namespace={'True': True, 'False': False, 'None': None}): """Evaluates s, safely. Useful for turning strings into tuples/lists/etc. without unsafely using eval().""" try: - node = compiler.parse(s) + node = ast.parse(s) except SyntaxError, e: raise ValueError, 'Invalid string: %s.' % e - nodes = compiler.parse(s).node.nodes + nodes = ast.parse(s).body if not nodes: - if node.__class__ is compiler.ast.Module: + if node.__class__ is ast.Module: return node.doc else: raise ValueError, format('Unsafe string: %q', s) node = nodes[0] - if node.__class__ is not compiler.ast.Discard: - raise ValueError, format('Invalid expression: %q', s) - node = node.getChildNodes()[0] def checkNode(node): - if node.__class__ is compiler.ast.Const: + if node.__class__ is ast.Expr: + node = node.value + if node.__class__ in (ast.Num, + ast.Str, + _astStr2): return True - if node.__class__ in (compiler.ast.List, - compiler.ast.Tuple, - compiler.ast.Dict): - return all(checkNode, node.getChildNodes()) - if node.__class__ is compiler.ast.Name: - if node.name in namespace: + elif node.__class__ in (ast.List, + ast.Tuple): + return all([checkNode(x) for x in node.elts]) + elif node.__class__ is ast.Dict: + return all([checkNode(x) for x in node.values]) and \ + all([checkNode(x) for x in node.values]) + elif node.__class__ is ast.Name: + if node.id in namespace: return True else: return False