Commit 478f967a by Ned Batchelder

We would fail if a global was defined with a non-jsonable value inside a…

We would fail if a global was defined with a non-jsonable value inside a jsonable one.  Now we don't/
parent b95ea442
...@@ -43,6 +43,10 @@ def safe_exec(code, globals_dict, assumed_imports=None, files=None, python_path= ...@@ -43,6 +43,10 @@ def safe_exec(code, globals_dict, assumed_imports=None, files=None, python_path=
Returns None. Changes made by `code` are visible in `globals_dict`. Returns None. Changes made by `code` are visible in `globals_dict`.
""" """
print "--- Executing: -------"
print code
print
the_code = [] the_code = []
files = list(files or ()) files = list(files or ())
...@@ -86,7 +90,15 @@ def safe_exec(code, globals_dict, assumed_imports=None, files=None, python_path= ...@@ -86,7 +90,15 @@ def safe_exec(code, globals_dict, assumed_imports=None, files=None, python_path=
""" """
ok_types = (type(None), int, long, float, str, unicode, list, tuple, dict) ok_types = (type(None), int, long, float, str, unicode, list, tuple, dict)
bad_keys = ("__builtins__",) bad_keys = ("__builtins__",)
g_dict = {k:v for k,v in g_dict.iteritems() if isinstance(v, ok_types) and k not in bad_keys} def jsonable(v):
if not isinstance(v, ok_types):
return False
try:
json.dumps(v)
except Exception:
return False
return True
g_dict = {k:v for k,v in g_dict.iteritems() if jsonable(v) and k not in bad_keys}
""" """
# Write the globals back to the calling process. # Write the globals back to the calling process.
""" """
...@@ -124,8 +136,14 @@ def not_safe_exec(code, globals_dict, assumed_imports=None, files=None, python_p ...@@ -124,8 +136,14 @@ def not_safe_exec(code, globals_dict, assumed_imports=None, files=None, python_p
Used to emulate reading data through a serialization straw. Used to emulate reading data through a serialization straw.
""" """
ok_types = (type(None), int, long, float, str, unicode, list, tuple, dict)
bad_keys = ("__builtins__",)
jd = {} jd = {}
for k,v in d.iteritems(): for k,v in d.iteritems():
if not isinstance(v, ok_types):
continue
if k in bad_keys:
continue
try: try:
json.dumps(v) json.dumps(v)
except TypeError: except TypeError:
......
...@@ -59,6 +59,14 @@ class SafeExecTests(object): ...@@ -59,6 +59,14 @@ class SafeExecTests(object):
self.safe_exec("a = 17; print 'hi!'", g) self.safe_exec("a = 17; print 'hi!'", g)
self.assertEqual(g['a'], 17) self.assertEqual(g['a'], 17)
def test_importing_lots_of_crap(self):
g = {}
self.safe_exec(textwrap.dedent("""\
from numpy import *
a = 1723
"""), g)
self.assertEqual(g['a'], 1723)
class TestSafeExec(SafeExecTests, unittest.TestCase): class TestSafeExec(SafeExecTests, unittest.TestCase):
"""Run SafeExecTests, with the real safe_exec.""" """Run SafeExecTests, with the real safe_exec."""
......
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