Please review this at http://codereview.appspot.com/178050

Affected files:
  M trytond/tools/misc.py


Index: trytond/tools/misc.py
===================================================================
--- a/trytond/tools/misc.py
+++ b/trytond/tools/misc.py
@@ -20,6 +20,11 @@
     import StringIO
 import dis
 import datetime
+try:
+    import hashlib
+except ImportError:
+    hashlib = None
+    import md5

 def find_in_path(name):
     if os.name == "nt":
@@ -510,23 +515,41 @@
     ] if x in dis.opmap)


+_SAFE_EVAL_CACHE = {}
+_SAFE_EVAL_CACHE_LOCK = Lock()
+
 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()
+    _SAFE_EVAL_CACHE_LOCK.acquire()
+    if key in _SAFE_EVAL_CACHE:
+        c = _SAFE_EVAL_CACHE[key]
+        _SAFE_EVAL_CACHE_LOCK.release()
+    else:
+        _SAFE_EVAL_CACHE_LOCK.release()
+        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])
+        _SAFE_EVAL_CACHE_LOCK.acquire()
+        if len(_SAFE_EVAL_CACHE) > 1024:
+            _SAFE_EVAL_CACHE.clear()
+        _SAFE_EVAL_CACHE[key] = c
+        _SAFE_EVAL_CACHE_LOCK.release()
     return eval(c, {'__builtins__': {
         'True': True,
         'False': False,

-- 
Cédric Krier

B2CK SPRL
Rue de Rotterdam, 4
4000 Liège
Belgium
Tel: +32 472 54 46 59
Email: [email protected]
Jabber: [email protected]
Website: http://www.b2ck.com/
twitter: http://twitter.com/cedrickrier
identi.ca: http://identi.ca/cedrickrier

Attachment: pgpweUs8uXZY3.pgp
Description: PGP signature

Reply via email to