Skip to content

Commit 5a5e6db

Browse files
wiredfoolhugovk
authored andcommitted
Fix EPS DOS on _open -- CVE-2021-28677
* 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
1 parent 3bf5edd commit 5a5e6db

File tree

3 files changed

+18
-5
lines changed

3 files changed

+18
-5
lines changed
Binary file not shown.

Tests/test_file_eps.py

+14-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import io
2-
32
import pytest
43

54
from PIL import EpsImagePlugin, Image, features
@@ -264,3 +263,17 @@ def test_emptyline():
264263
assert image.mode == "RGB"
265264
assert image.size == (460, 352)
266265
assert image.format == "EPS"
266+
267+
268+
@pytest.mark.timeout(timeout=5)
269+
@pytest.mark.parametrize(
270+
"test_file",
271+
[
272+
("Tests/images/timeout-d675703545fee17acab56e5fec644c19979175de.eps")
273+
],
274+
)
275+
def test_timeout(test_file):
276+
with open(test_file, "rb") as f:
277+
with pytest.raises(Image.UnidentifiedImageError):
278+
with Image.open(f):
279+
pass

src/PIL/EpsImagePlugin.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -170,20 +170,20 @@ def seek(self, offset, whence=io.SEEK_SET):
170170
self.fp.seek(offset, whence)
171171

172172
def readline(self):
173-
s = self.char or b""
173+
s = [self.char or b""]
174174
self.char = None
175175

176176
c = self.fp.read(1)
177-
while c not in b"\r\n":
178-
s = s + c
177+
while (c not in b"\r\n") and len(c):
178+
s.append(c)
179179
c = self.fp.read(1)
180180

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

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

188188

189189
def _accept(prefix):

0 commit comments

Comments
 (0)