mirror of
https://github.com/Mikaela/Limnoria.git
synced 2024-11-27 05:09:23 +01:00
Added safeEval.
This commit is contained in:
parent
900f2a97f9
commit
901a225619
42
src/utils.py
42
src/utils.py
@ -43,6 +43,7 @@ import md5
|
|||||||
import sha
|
import sha
|
||||||
import string
|
import string
|
||||||
import sgmllib
|
import sgmllib
|
||||||
|
import compiler
|
||||||
import textwrap
|
import textwrap
|
||||||
import htmlentitydefs
|
import htmlentitydefs
|
||||||
|
|
||||||
@ -408,12 +409,47 @@ def flatten(seq, strings=False):
|
|||||||
def saltHash(password, salt=None, hash='sha'):
|
def saltHash(password, salt=None, hash='sha'):
|
||||||
if salt is None:
|
if salt is None:
|
||||||
salt = mktemp()[:8]
|
salt = mktemp()[:8]
|
||||||
if hash == 'md5':
|
if hash == 'sha':
|
||||||
hasher = md5.md5
|
|
||||||
elif hash == 'sha':
|
|
||||||
hasher = sha.sha
|
hasher = sha.sha
|
||||||
|
elif hash == 'md5':
|
||||||
|
hasher = md5.md5
|
||||||
return '|'.join([salt, hasher(salt + password).hexdigest()])
|
return '|'.join([salt, hasher(salt + password).hexdigest()])
|
||||||
|
|
||||||
|
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()."""
|
||||||
|
node = compiler.parse(s)
|
||||||
|
nodes = compiler.parse(s).node.nodes
|
||||||
|
if not nodes:
|
||||||
|
if node.__class__ is compiler.ast.Module:
|
||||||
|
return node.doc
|
||||||
|
else:
|
||||||
|
raise ValueError, 'Unsafe string.'
|
||||||
|
node = nodes[0]
|
||||||
|
if node.__class__ is not compiler.ast.Discard:
|
||||||
|
raise ValueError, 'Invalid expression: %s'
|
||||||
|
node = node.getChildNodes()[0]
|
||||||
|
def checkNode(node):
|
||||||
|
if node.__class__ is compiler.ast.Const:
|
||||||
|
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:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
if checkNode(node):
|
||||||
|
return eval(s, namespace, namespace)
|
||||||
|
else:
|
||||||
|
raise ValueError, 'Unsafe string.'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class IterableMap(object):
|
class IterableMap(object):
|
||||||
"""Define .iteritems() in a class and subclass this to get the other iters.
|
"""Define .iteritems() in a class and subclass this to get the other iters.
|
||||||
"""
|
"""
|
||||||
|
@ -280,6 +280,14 @@ class UtilsTest(unittest.TestCase):
|
|||||||
(salt, hash) = s.split('|')
|
(salt, hash) = s.split('|')
|
||||||
self.assertEqual(utils.saltHash('jemfinch', salt=salt), s)
|
self.assertEqual(utils.saltHash('jemfinch', salt=salt), s)
|
||||||
|
|
||||||
|
def testSafeEval(self):
|
||||||
|
for s in ['1', '()', '(1,)', '[]', '{}', '{1:2}', '{1:(2,3)}',
|
||||||
|
'1.0', '[1,2,3]', 'True', 'False', 'None',
|
||||||
|
'(True,False,None)', '"foo"', '{"foo": "bar"}']:
|
||||||
|
self.assertEqual(eval(s), utils.safeEval(s))
|
||||||
|
for s in ['lambda: 2', 'import foo', 'foo.bar']:
|
||||||
|
self.assertRaises(ValueError, utils.safeEval, s)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user