Add cache to safe_eval

This commit is contained in:
Cédric Krier committed 2009-12-17 11:26:44 +01:00
1 parent 38996b2479
commit 3d06a48a97
2 files changed
+25 -14

No files matched your search

+1
View File
@@ -1,3 +1,4 @@
* Add cache to safe_eval
* Use versioned configuration directory
* Next and Previous scroll per page on list and don't loop
* Add AccelGroup on search windows (CTRL+Return)
+24 -14
View File
@@ -1180,24 +1180,34 @@ _ALLOWED_CODES = set(dis.opmap[x] for x in [
'DELETE_NAME', 'JUMP_IF_TRUE', 'JUMP_IF_FALSE', 'BINARY_SUBSCR',
] if x in dis.opmap)
_SAFE_EVAL_CACHE = {}
def safe_eval(source, data=None):
if '__subclasses__' in source:
raise ValueError('__subclasses__ not allowed')
c = compile(source, '', 'eval')
codes = []
s = c.co_code
i = 0
while i < len(s):
code = ord(s[i])
codes.append(code)
if code >= dis.HAVE_ARGUMENT:
i += 3
else:
i += 1
for code in codes:
if code not in _ALLOWED_CODES:
raise ValueError('opcode %s not allowed' % dis.opname[code])
if hashlib:
key = hashlib.md5(source).hexdigest()
else:
key = md5.new(source).hexdigest()
c = _SAFE_EVAL_CACHE.get(key)
if not c:
c = compile(source, '', 'eval')
codes = []
s = c.co_code
i = 0
while i < len(s):
code = ord(s[i])
codes.append(code)
if code >= dis.HAVE_ARGUMENT:
i += 3
else:
i += 1
for code in codes:
if code not in _ALLOWED_CODES:
raise ValueError('opcode %s not allowed' % dis.opname[code])
if len(_SAFE_EVAL_CACHE) > 1024:
_SAFE_EVAL_CACHE.clear()
_SAFE_EVAL_CACHE[key] = c
return eval(c, {'__builtins__': {
'True': True,
'False': False,