Skip to content

Commit

Permalink
Fix EPS DOS on _open -- CVE-2021-28677
Browse files Browse the repository at this point in the history
* The readline used in EPS has to deal with any combination of \r and
  \n as line endings. It used an accidentally quadratic method of
  accumulating lines while looking for a line ending.
* A malicious EPS file could use this to perform a DOS of Pillow in
  the open phase, before an image was accepted for opening.
* This dates to the PIL Fork
  • Loading branch information
wiredfool authored and hugovk committed Apr 1, 2021
1 parent 3bf5edd commit 5a5e6db
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 5 deletions.
Binary file not shown.
15 changes: 14 additions & 1 deletion Tests/test_file_eps.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import io

import pytest

from PIL import EpsImagePlugin, Image, features
Expand Down Expand Up @@ -264,3 +263,17 @@ def test_emptyline():
assert image.mode == "RGB"
assert image.size == (460, 352)
assert image.format == "EPS"


@pytest.mark.timeout(timeout=5)
@pytest.mark.parametrize(
"test_file",
[
("Tests/images/timeout-d675703545fee17acab56e5fec644c19979175de.eps")
],
)
def test_timeout(test_file):
with open(test_file, "rb") as f:
with pytest.raises(Image.UnidentifiedImageError):
with Image.open(f):
pass
8 changes: 4 additions & 4 deletions src/PIL/EpsImagePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,20 +170,20 @@ def seek(self, offset, whence=io.SEEK_SET):
self.fp.seek(offset, whence)

def readline(self):
s = self.char or b""
s = [self.char or b""]
self.char = None

c = self.fp.read(1)
while c not in b"\r\n":
s = s + c
while (c not in b"\r\n") and len(c):
s.append(c)
c = self.fp.read(1)

self.char = self.fp.read(1)
# line endings can be 1 or 2 of \r \n, in either order
if self.char in b"\r\n":
self.char = None

return s.decode("latin-1")
return b"".join(s).decode("latin-1")


def _accept(prefix):
Expand Down

0 comments on commit 5a5e6db

Please # to comment.