From eed2a0e3c4e97ebabfdf6b4d607b87f8245c0232 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Wed, 19 Aug 2026 10:41:18 +1000 Subject: [PATCH 1/2] Rename variable --- src/PIL/MspImagePlugin.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/PIL/MspImagePlugin.py b/src/PIL/MspImagePlugin.py index 9df5cfd9345..506bca92850 100644 --- a/src/PIL/MspImagePlugin.py +++ b/src/PIL/MspImagePlugin.py @@ -126,14 +126,14 @@ def decode(self, buffer: Image.DecoderInput) -> tuple[int, int]: msg = "Truncated MSP file in row map" raise OSError(msg) from e - for x, rowlen in enumerate(rowmap): + for y, rowlen in enumerate(rowmap): try: if rowlen == 0: img.write(blank_line) continue row = self.fd.read(rowlen) if len(row) != rowlen: - msg = f"Truncated MSP file, expected {rowlen} bytes on row {x}" + msg = f"Truncated MSP file, expected {rowlen} bytes on row {y}" raise OSError(msg) idx = 0 while idx < rowlen: @@ -149,7 +149,7 @@ def decode(self, buffer: Image.DecoderInput) -> tuple[int, int]: idx += runcount except struct.error as e: - msg = f"Corrupted MSP file in row {x}" + msg = f"Corrupted MSP file in row {y}" raise OSError(msg) from e self.set_as_raw(img.getvalue(), "1") From d0b6ba270c79a9da31a0ec366086210d9c5cd642 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Wed, 19 Aug 2026 10:40:39 +1000 Subject: [PATCH 2/2] Use bytearray instead of BytesIO --- src/PIL/MspImagePlugin.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/PIL/MspImagePlugin.py b/src/PIL/MspImagePlugin.py index 506bca92850..eba0e98a436 100644 --- a/src/PIL/MspImagePlugin.py +++ b/src/PIL/MspImagePlugin.py @@ -24,7 +24,6 @@ # See also: https://www.fileformat.info/format/mspaint/egff.htm from __future__ import annotations -import io import struct from typing import IO @@ -115,7 +114,7 @@ class MspDecoder(ImageFile.PyDecoder): def decode(self, buffer: Image.DecoderInput) -> tuple[int, int]: assert self.fd is not None - img = io.BytesIO() + data = bytearray() blank_line = bytearray((0xFF,) * ((self.state.xsize + 7) // 8)) try: self.fd.seek(32) @@ -129,7 +128,7 @@ def decode(self, buffer: Image.DecoderInput) -> tuple[int, int]: for y, rowlen in enumerate(rowmap): try: if rowlen == 0: - img.write(blank_line) + data += blank_line continue row = self.fd.read(rowlen) if len(row) != rowlen: @@ -141,18 +140,18 @@ def decode(self, buffer: Image.DecoderInput) -> tuple[int, int]: idx += 1 if runtype == 0: runcount, runval = struct.unpack_from("Bc", row, idx) - img.write(runval * runcount) + data += runval * runcount idx += 2 else: runcount = runtype - img.write(row[idx : idx + runcount]) + data += row[idx : idx + runcount] idx += runcount except struct.error as e: msg = f"Corrupted MSP file in row {y}" raise OSError(msg) from e - self.set_as_raw(img.getvalue(), "1") + self.set_as_raw(bytes(data), "1") return -1, 0