Skip to content

Commit

Permalink
Merge pull request #5923 from radarhere/imagemath_eval
Browse files Browse the repository at this point in the history
Restrict builtins for ImageMath.eval()
  • Loading branch information
mergify[bot] authored Jan 2, 2022
2 parents 1efb1d9 + 8531b01 commit d7f60d1
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 1 deletion.
7 changes: 7 additions & 0 deletions Tests/test_imagemath.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import pytest

from PIL import Image, ImageMath


Expand Down Expand Up @@ -50,6 +52,11 @@ def test_ops():
assert pixel(ImageMath.eval("float(B)**33", images)) == "F 8589934592.0"


def test_prevent_exec():
with pytest.raises(ValueError):
ImageMath.eval("exec('pass')")


def test_logical():
assert pixel(ImageMath.eval("not A", images)) == 0
assert pixel(ImageMath.eval("A and B", images)) == "L 2"
Expand Down
8 changes: 8 additions & 0 deletions docs/releasenotes/9.0.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,14 @@ To prevent attempts to slow down loading times for images, if an image has conse
duplicate tiles that only differ by their offset, only load the last tile. Credit to
Google's `OSS-Fuzz`_ project for finding this issue.

Restrict builtins available to ImageMath.eval
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

To limit :py:class:`PIL.ImageMath` to working with images, Pillow will now restrict the
builtins available to :py:meth:`PIL.ImageMath.eval`. This will help prevent problems
arising if users evaluate arbitrary expressions, such as
``ImageMath.eval("exec(exit())")``.

Fixed ImagePath.Path array handling
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Expand Down
7 changes: 6 additions & 1 deletion src/PIL/ImageMath.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,12 @@ def eval(expression, _dict={}, **kw):
if hasattr(v, "im"):
args[k] = _Operand(v)

out = builtins.eval(expression, args)
code = compile(expression, "<string>", "eval")
for name in code.co_names:
if name not in args and name != "abs":
raise ValueError(f"'{name}' not allowed")

out = builtins.eval(expression, {"__builtins": {"abs": abs}}, args)
try:
return out.im
except AttributeError:
Expand Down

0 comments on commit d7f60d1

Please sign in to comment.