From d402fe0b17e75ca6f6869dbf356200754c6d21c1 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Thu, 29 Sep 2022 08:22:01 +1000 Subject: [PATCH 1/2] Added IMT tests --- Tests/images/bw_gradient.imt | Bin 0 -> 2599 bytes Tests/test_file_imt.py | 19 +++++++++++++++++++ src/PIL/ImtImagePlugin.py | 6 +++--- 3 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 Tests/images/bw_gradient.imt create mode 100644 Tests/test_file_imt.py diff --git a/Tests/images/bw_gradient.imt b/Tests/images/bw_gradient.imt new file mode 100644 index 0000000000000000000000000000000000000000..d765cf95facfcb7cb2dbd63b61a6e48d213c31b5 GIT binary patch literal 2599 zcmdN&&d<$F%`4$5&rB)FP%ttz+{(>E|QGBzQN=`{lOV7y6%FfBn%P%M_ zDlRE4E3c@ms;;T6t8Zv*YHn$5Ywzgn>h9_7>z^=j(&Q;qr%j(RbJpxRbLY)puyE1h zB}NRWEt>3V5)8;K(w{73CbJy-Yd-v@>aPZLKBS()NKXLNZ=`&}~oxgDL z(&Z~xuU)@!^VaPo;%Tz5np>)8{W=zkUDl^Vjb`fB*d- c_5W!6kEZ|8{6AX$jh6qT_1|dyKhoMi07e@JTmS$7 literal 0 HcmV?d00001 diff --git a/Tests/test_file_imt.py b/Tests/test_file_imt.py new file mode 100644 index 00000000000..f56acc42949 --- /dev/null +++ b/Tests/test_file_imt.py @@ -0,0 +1,19 @@ +import io + +import pytest + +from PIL import Image, ImtImagePlugin + +from .helper import assert_image_equal_tofile + + +def test_sanity(): + with Image.open("Tests/images/bw_gradient.imt") as im: + assert_image_equal_tofile(im, "Tests/images/bw_gradient.png") + + +@pytest.mark.parametrize("data", (b"\n", b"\n-", b"width 1\n")) +def test_invalid_file(data): + with io.BytesIO(data) as fp: + with pytest.raises(SyntaxError): + ImtImagePlugin.ImtImageFile(fp) diff --git a/src/PIL/ImtImagePlugin.py b/src/PIL/ImtImagePlugin.py index 5790acdaf52..5bcb959f143 100644 --- a/src/PIL/ImtImagePlugin.py +++ b/src/PIL/ImtImagePlugin.py @@ -74,13 +74,13 @@ def _open(self): if not m: break k, v = m.group(1, 2) - if k == "width": + if k == b"width": xsize = int(v) self._size = xsize, ysize - elif k == "height": + elif k == b"height": ysize = int(v) self._size = xsize, ysize - elif k == "pixel" and v == "n8": + elif k == b"pixel" and v == b"n8": self.mode = "L" From cb2243713c5241f49336e8892b354bccf250e586 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Wed, 28 Sep 2022 21:36:07 +1000 Subject: [PATCH 2/2] Only read a maximum of 100 bytes at a time --- src/PIL/ImtImagePlugin.py | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/PIL/ImtImagePlugin.py b/src/PIL/ImtImagePlugin.py index 5bcb959f143..dc707801274 100644 --- a/src/PIL/ImtImagePlugin.py +++ b/src/PIL/ImtImagePlugin.py @@ -39,15 +39,19 @@ def _open(self): # Quick rejection: if there's not a LF among the first # 100 bytes, this is (probably) not a text header. - if b"\n" not in self.fp.read(100): + buffer = self.fp.read(100) + if b"\n" not in buffer: raise SyntaxError("not an IM file") - self.fp.seek(0) xsize = ysize = 0 while True: - s = self.fp.read(1) + if buffer: + s = buffer[:1] + buffer = buffer[1:] + else: + s = self.fp.read(1) if not s: break @@ -55,7 +59,12 @@ def _open(self): # image data begins self.tile = [ - ("raw", (0, 0) + self.size, self.fp.tell(), (self.mode, 0, 1)) + ( + "raw", + (0, 0) + self.size, + self.fp.tell() - len(buffer), + (self.mode, 0, 1), + ) ] break @@ -63,8 +72,11 @@ def _open(self): else: # read key/value pair - # FIXME: dangerous, may read whole file - s = s + self.fp.readline() + if b"\n" not in buffer: + buffer += self.fp.read(100) + lines = buffer.split(b"\n") + s += lines.pop(0) + buffer = b"\n".join(lines) if len(s) == 1 or len(s) > 100: break if s[0] == ord(b"*"):