File 020-CVE-2021-28677.patch of Package python-Pillow

From 5a5e6db0abf4e7a638fb1b3408c4e495a096cb92 Mon Sep 17 00:00:00 2001
From: Eric Soroos <eric-github@soroos.net>
Date: Mon, 8 Mar 2021 20:31:41 +0100
Subject: [PATCH] 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
---
 ...675703545fee17acab56e5fec644c19979175de.eps | Bin 0 -> 549784 bytes
 Tests/test_file_eps.py                         |  15 ++++++++++++++-
 PIL/EpsImagePlugin.py                      |   8 ++++----
 3 files changed, 18 insertions(+), 5 deletions(-)
 create mode 100644 Tests/images/timeout-d675703545fee17acab56e5fec644c19979175de.eps

diff --git a/Tests/test_file_eps.py b/Tests/test_file_eps.py
index ea91375dadb..e616ffa0cf6 100644
--- a/Tests/test_file_eps.py
+++ b/Tests/test_file_eps.py
@@ -267,7 +267,15 @@ def test_open_eps(self):
 
         # Assert
         self.assertEqual(img.mode, "RGB")
+
+    # @pytest.mark.timeout(timeout=5) # not available in unittest
+    def test_timeout(self):
+        test_file = "Tests/images/timeout-d675703545fee17acab56e5fec644c19979175de.eps"
+        with open(test_file, "rb") as f:
+            with self.assertRaises(IOError):
+                with Image.open(f):
+                    pass
 
 
 if __name__ == '__main__':
     unittest.main()
diff --git a/PIL/EpsImagePlugin.py b/PIL/EpsImagePlugin.py
index dc61f48edc9..3bf8ee0ab35 100644
--- a/PIL/EpsImagePlugin.py
+++ b/PIL/EpsImagePlugin.py
@@ -166,12 +166,12 @@ 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)
@@ -179,7 +179,7 @@ def readline(self):
         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):
openSUSE Build Service is sponsored by