|
|
cd6656 |
diff --git a/Tests/test_imagemath.py b/Tests/test_imagemath.py
|
|
|
cd6656 |
index 2329b74..d3b7ba3 100644
|
|
|
cd6656 |
--- a/Tests/test_imagemath.py
|
|
|
cd6656 |
+++ b/Tests/test_imagemath.py
|
|
|
cd6656 |
@@ -58,6 +58,12 @@ class TestImageMath(PillowTestCase):
|
|
|
cd6656 |
self.assertEqual(pixel(
|
|
|
cd6656 |
ImageMath.eval("float(B)**33", images)), "F 8589934592.0")
|
|
|
cd6656 |
|
|
|
cd6656 |
+ def test_prevent_exec(self):
|
|
|
cd6656 |
+ self.assertRaises(ValueError, ImageMath.eval("exec('pass')"))
|
|
|
cd6656 |
+ self.assertRaises(ValueError, ImageMath.eval("(lambda: exec('pass'))()"))
|
|
|
cd6656 |
+ self.assertRaises(ValueError, ImageMath.eval("(lambda: (lambda: exec('pass'))())()"))
|
|
|
cd6656 |
+
|
|
|
cd6656 |
+
|
|
|
cd6656 |
def test_logical(self):
|
|
|
cd6656 |
self.assertEqual(pixel(ImageMath.eval("not A", images)), 0)
|
|
|
cd6656 |
self.assertEqual(pixel(ImageMath.eval("A and B", images)), "L 2")
|
|
|
cd6656 |
diff --git a/src/PIL/ImageMath.py b/src/PIL/ImageMath.py
|
|
|
cd6656 |
index c5bea70..13839e4 100644
|
|
|
cd6656 |
--- a/src/PIL/ImageMath.py
|
|
|
cd6656 |
+++ b/src/PIL/ImageMath.py
|
|
|
cd6656 |
@@ -263,7 +263,18 @@ def eval(expression, _dict={}, **kw):
|
|
|
cd6656 |
if hasattr(v, "im"):
|
|
|
cd6656 |
args[k] = _Operand(v)
|
|
|
cd6656 |
|
|
|
cd6656 |
- out = builtins.eval(expression, args)
|
|
|
cd6656 |
+ compiled_code = compile(expression, "<string>", "eval")
|
|
|
cd6656 |
+ def scan(code):
|
|
|
cd6656 |
+ for const in code.co_consts:
|
|
|
cd6656 |
+ if type(const) == type(compiled_code):
|
|
|
cd6656 |
+ scan(const)
|
|
|
cd6656 |
+
|
|
|
cd6656 |
+ for name in code.co_names:
|
|
|
cd6656 |
+ if name not in args and name != "abs":
|
|
|
cd6656 |
+ raise ValueError(f"'{name}' not allowed")
|
|
|
cd6656 |
+
|
|
|
cd6656 |
+ scan(compiled_code)
|
|
|
cd6656 |
+ out = builtins.eval(expression, {"__builtins": {"abs": abs}}, args)
|
|
|
cd6656 |
try:
|
|
|
cd6656 |
return out.im
|
|
|
cd6656 |
except AttributeError:
|