File 0008-Corrected-negative-seeks.patch of Package python-Pillow

From 87c43b66a5ffe0d21e04dce631a5fd4004e6021b Mon Sep 17 00:00:00 2001
From: Andrew Murray <radarhere@users.noreply.github.com>
Date: Sun, 29 Sep 2019 14:16:30 +1000
Subject: [PATCH] Corrected negative seeks

---
 Tests/test_file_psd.py                     |   9 +++++++++
 Tests/test_imagefile.py                    |   8 ++++++++
 src/PIL/PsdImagePlugin.py                  |   6 ++++--
 src/libImaging/RawDecode.c                 |  11 +++++++++--
 4 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/Tests/test_file_psd.py b/Tests/test_file_psd.py
index f55ee1dcbb..8381ceaefc 100644
--- a/Tests/test_file_psd.py
+++ b/Tests/test_file_psd.py
@@ -15,6 +15,15 @@ def test_sanity(self):
         self.assertEqual(im.mode, "RGB")
         self.assertEqual(im.size, (128, 128))
         self.assertEqual(im.format, "PSD")
+
+    def test_combined_larger_than_size(self):
+        # The 'combined' sizes of the individual parts is larger than the
+        # declared 'size' of the extra data field, resulting in a backwards seek.
+
+        # If we instead take the 'size' of the extra data field as the source of truth,
+        # then the seek can't be negative
+        with self.assertRaises(IOError):
+            Image.open("Tests/images/combined_larger_than_size.psd")
 
 
 if __name__ == '__main__':
diff --git a/Tests/test_imagefile.py b/Tests/test_imagefile.py
index ceccd22855..a367f62dfa 100644
--- a/Tests/test_imagefile.py
+++ b/Tests/test_imagefile.py
@@ -91,8 +91,16 @@ def test_safeblock(self):
             ImageFile.SAFEBLOCK = SAFEBLOCK
 
         self.assert_image_equal(im1, im2)
 
+    def test_negative_stride(self):
+        with open("Tests/images/raw_negative_stride.bin", "rb") as f:
+            input = f.read()
+        p = ImageFile.Parser()
+        p.feed(input)
+        with self.assertRaises(IOError):
+            p.close()
+
 
 if __name__ == '__main__':
     unittest.main()
 
diff --git a/PIL/PsdImagePlugin.py b/PIL/PsdImagePlugin.py
index 9eb0c09669..f72ad5f443 100644
--- a/PIL/PsdImagePlugin.py
+++ b/PIL/PsdImagePlugin.py
@@ -207,9 +207,11 @@ def _layerinfo(file):
         # skip over blend flags and extra information
         filler = read(12)
         name = ""
-        size = i32(read(4))
+        size = i32(read(4))  # length of the extra data field
         combined = 0
         if size:
+            data_end = file.tell() + size
+
             length = i32(read(4))
             if length:
                 mask_y = i32(read(4))
@@ -231,7 +233,7 @@ def _layerinfo(file):
                 name = read(length).decode('latin-1', 'replace')
             combined += length + 1
 
-        file.seek(size - combined, 1)
+            file.seek(data_end)
         layers.append((name, mode, (x0, y0, x1, y1)))
 
     # get tiles
diff --git a/libImaging/RawDecode.c b/libImaging/RawDecode.c
index 774d4245b8..c069bdb886 100644
--- a/libImaging/RawDecode.c
+++ b/libImaging/RawDecode.c
@@ -33,8 +33,15 @@ ImagingRawDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
 
 	/* get size of image data and padding */
 	state->bytes = (state->xsize * state->bits + 7) / 8;
-	rawstate->skip = (rawstate->stride) ?
-	    rawstate->stride - state->bytes : 0;
+	if (rawstate->stride) {
+	    rawstate->skip = rawstate->stride - state->bytes;
+	    if (rawstate->skip < 0) {
+	        state->errcode = IMAGING_CODEC_CONFIG;
+	        return -1;
+	    }
+	} else {
+	    rawstate->skip = 0;
+	}
 
 	/* check image orientation */
 	if (state->ystep < 0) {
openSUSE Build Service is sponsored by