Commit baa6b4e3 by Ned Batchelder

The cache key for safe_exec has to be hashed to keep it a reasonable size.

parent 09fbbe7b
......@@ -4,6 +4,8 @@ from codejail.safe_exec import safe_exec as codejail_safe_exec
from codejail.safe_exec import json_safe
from . import lazymod
import hashlib
# Establish the Python environment for Capa.
# Capa assumes float-friendly division always.
# The name "random" is a properly-seeded stand-in for the random module.
......@@ -53,7 +55,10 @@ def safe_exec(code, globals_dict, random_seed=None, python_path=None, cache=None
# Check the cache for a previous result.
if cache:
canonical_globals = sorted(json_safe(globals_dict).iteritems())
key = "safe_exec %r %s %r" % (random_seed, code, canonical_globals)
md5er = hashlib.md5()
md5er.update(code)
md5er.update(repr(canonical_globals))
key = "safe_exec %r %s" % (random_seed, md5er.hexdigest())
cached = cache.get(key)
if cached is not None:
globals_dict.update(cached)
......
......@@ -65,9 +65,13 @@ class DictCache(object):
self.cache = d
def get(self, key):
# Actual cache implementations have limits on key length
assert len(key) <= 250
return self.cache.get(key)
def set(self, key, value):
# Actual cache implementations have limits on key length
assert len(key) <= 250
self.cache[key] = value
......@@ -90,3 +94,13 @@ class TestSafeExecCaching(unittest.TestCase):
g = {}
safe_exec("a = int(math.pi)", g, cache=DictCache(cache))
self.assertEqual(g['a'], 17)
def test_cache_large_code_chunk(self):
# Caching used to die on memcache with more than 250 bytes of code.
# Check that it doesn't any more.
code = "a = 0\n" + ("a += 1\n" * 12345)
g = {}
cache = {}
safe_exec(code, g, cache=DictCache(cache))
self.assertEqual(g['a'], 12345)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment