From a232e8ae44b00e063482d600f6a01b492c9a95b9 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Sat, 24 Jan 2026 11:15:26 +1100 Subject: [PATCH 1/5] Stop reading when the end of the file is reached --- src/PIL/DdsImagePlugin.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/PIL/DdsImagePlugin.py b/src/PIL/DdsImagePlugin.py index 312f602a6b1..063df197443 100644 --- a/src/PIL/DdsImagePlugin.py +++ b/src/PIL/DdsImagePlugin.py @@ -509,7 +509,10 @@ def decode(self, buffer: bytes | Image.SupportsArrayInterface) -> tuple[int, int bytecount = bitcount // 8 dest_length = self.state.xsize * self.state.ysize * len(masks) while len(data) < dest_length: - value = int.from_bytes(self.fd.read(bytecount), "little") + bytes_read = self.fd.read(bytecount) + if len(bytes_read) < bytecount: + break + value = int.from_bytes(bytes_read, "little") for i, mask in enumerate(masks): masked_value = value & mask # Remove the zero padding, and scale it to 8 bits From 4b43e717c1422df5f6684c91d2aa546c7b70f76c Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Sat, 24 Jan 2026 11:08:38 +1100 Subject: [PATCH 2/5] Do not attempt to read zero bytes --- src/PIL/DdsImagePlugin.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/PIL/DdsImagePlugin.py b/src/PIL/DdsImagePlugin.py index 063df197443..897c0741ff4 100644 --- a/src/PIL/DdsImagePlugin.py +++ b/src/PIL/DdsImagePlugin.py @@ -489,9 +489,14 @@ class DdsRgbDecoder(ImageFile.PyDecoder): _pulls_fd = True def decode(self, buffer: bytes | Image.SupportsArrayInterface) -> tuple[int, int]: - assert self.fd is not None bitcount, masks = self.args + data = bytearray() + bytecount = bitcount // 8 + if not bytecount: + self.set_as_raw(data) + return -1, 0 + # Some masks will be padded with zeros, e.g. R 0b11 G 0b1100 # Calculate how many zeros each mask is padded with mask_offsets = [] @@ -505,8 +510,7 @@ def decode(self, buffer: bytes | Image.SupportsArrayInterface) -> tuple[int, int mask_offsets.append(offset) mask_totals.append(mask >> offset) - data = bytearray() - bytecount = bitcount // 8 + assert self.fd is not None dest_length = self.state.xsize * self.state.ysize * len(masks) while len(data) < dest_length: bytes_read = self.fd.read(bytecount) From d87946e10b85f274145c4926f474b336faa7a827 Mon Sep 17 00:00:00 2001 From: Eric Soroos Date: Thu, 22 Jan 2026 22:35:04 +0100 Subject: [PATCH 3/5] add a selection of test cases from oss-fuzz --- Tests/test_file_dds.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Tests/test_file_dds.py b/Tests/test_file_dds.py index 931ff02f1fb..98b9e0fb586 100644 --- a/Tests/test_file_dds.py +++ b/Tests/test_file_dds.py @@ -15,6 +15,7 @@ assert_image_similar, assert_image_similar_tofile, hopper, + timeout_unless_slower_valgrind, ) TEST_FILE_DXT1 = "Tests/images/dxt1-rgb-4bbp-noalpha_MipMaps-1.dds" @@ -540,3 +541,18 @@ def test_save_large_file(tmp_path: Path, pixel_format: str, mode: str) -> None: im = hopper(mode).resize((440, 440)) # should not error in valgrind im.save(tmp_path / "img.dds", pixel_format=pixel_format) + + +@timeout_unless_slower_valgrind(1) +@pytest.mark.parametrize( + "test_file", + [ + "Tests/images/timeout-041dd17dfde800360a47a172269df127af138c6b.dds", + "Tests/images/timeout-755a4d204f4208e3597ac3391edebee196462bd0.dds", + "Tests/images/timeout-52d106579505547091ef69b58341351a37c23e31.dds", + "Tests/images/timeout-c60a3d7314213624607bfb3e38d551a8b24a7435.dds", + ], +) +def test_timeout(test_file) -> None: + with Image.open(test_file) as im: + im.load() From 629c9bffe9abcc56a0d812a087b081eec2151893 Mon Sep 17 00:00:00 2001 From: Eric Soroos Date: Thu, 22 Jan 2026 22:48:36 +0100 Subject: [PATCH 4/5] added test images --- ...041dd17dfde800360a47a172269df127af138c6b.dds | Bin 0 -> 1858 bytes ...52d106579505547091ef69b58341351a37c23e31.dds | Bin 0 -> 3499 bytes ...755a4d204f4208e3597ac3391edebee196462bd0.dds | Bin 0 -> 22095 bytes ...c60a3d7314213624607bfb3e38d551a8b24a7435.dds | Bin 0 -> 131 bytes 4 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 Tests/images/timeout-041dd17dfde800360a47a172269df127af138c6b.dds create mode 100644 Tests/images/timeout-52d106579505547091ef69b58341351a37c23e31.dds create mode 100644 Tests/images/timeout-755a4d204f4208e3597ac3391edebee196462bd0.dds create mode 100644 Tests/images/timeout-c60a3d7314213624607bfb3e38d551a8b24a7435.dds diff --git a/Tests/images/timeout-041dd17dfde800360a47a172269df127af138c6b.dds b/Tests/images/timeout-041dd17dfde800360a47a172269df127af138c6b.dds new file mode 100644 index 0000000000000000000000000000000000000000..8831f8fb2947ba6982bbaded29dcdfccb0166e80 GIT binary patch literal 1858 zcmcgtdpOg382|ld%u!};xx_ZNI=M4aa+$28PEjL63t1QCmdkN;#H^cXEmoW^l1oJ^ zM2tEyx0Xvvl(LQ1p{PVs6x)7hJ9!@GuhW0$^FHtMem>vt`+eW%dB1~xbSuK*W}o5=E9;Xq>t zITouFBvPTFw16(_F*4B62f9dV6nn~%PM=VYLU2`O0#dX*f?Bl~&5+(tx(K=Hh7vm^+9sSQ zzMhCnsqm_((MKP~Cp6mgvr@rT!f(!PU&dp~VTDtV38ZE(kz%H)^PG_;KAmuS-5u0a zTltFA>DxpYK;9k@=C#lJ82`_%t~J&+8rn{RSk0cqKc3VU8ou{21I@gMK47Nz{fF*} zFdYq3Fz$rmk7O zI{TS*?Zri0mTBQvwchj^-B@MgZtT$qD@D0(@%x$sP8)`_)itV(7>O!o(R0?h;k>X> z6pcCYbg90Ed5qci7Zg(JbyIS)RZ5elsfWqk;VjPwmoBq>b3*6(<~}5@Cj}$LF;d8{ zF@qz4oLmEh2i%h)&p;x@ha3oFLw+EP!o*W>$s)zpTvOY$Iy%hRVyvfTN@Y8wJeF6_$ih<1+A{~VLI436roCnW#+X}yXG=)Z@3Pdc%wfsnS{o~I0A1CFuT zQt66TU(&0V>|o7B6L@E#xYFAwmN?tUDMaUXZ`8{omq!l10#o@+k8{=(X9OpiECAS z@k>%hxD5hT+*llLlk;Y3Fdj4dpM#0w{m+9b$QjHDw@S7{r`W?Tle6Jw| z#lTl!(qAWd|4^CNAkQy$9kF!S;{%20lgDJe9rGS2oAFoze3;te@ig_u!^7sPB1AL* zv`;bJhx1#y+!@ZxDvDo?<-V;f+OqNvwfFWEvLB63r&hNax0W6R{ AWdHyG literal 0 HcmV?d00001 diff --git a/Tests/images/timeout-52d106579505547091ef69b58341351a37c23e31.dds b/Tests/images/timeout-52d106579505547091ef69b58341351a37c23e31.dds new file mode 100644 index 0000000000000000000000000000000000000000..2815eb0105920b8943f3ba816746009d8bdb5e60 GIT binary patch literal 3499 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 PKe$AFOp~hmRE>WEYPaqG literal 0 HcmV?d00001 diff --git a/Tests/images/timeout-755a4d204f4208e3597ac3391edebee196462bd0.dds b/Tests/images/timeout-755a4d204f4208e3597ac3391edebee196462bd0.dds new file mode 100644 index 0000000000000000000000000000000000000000..1debdffa8d996101f7ce9cf713e6da61f15df55d GIT binary patch literal 22095 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 Date: Sat, 24 Jan 2026 11:13:04 +1100 Subject: [PATCH 5/5] Catch error --- Tests/test_file_dds.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Tests/test_file_dds.py b/Tests/test_file_dds.py index 98b9e0fb586..6d0ae20eaa4 100644 --- a/Tests/test_file_dds.py +++ b/Tests/test_file_dds.py @@ -15,7 +15,6 @@ assert_image_similar, assert_image_similar_tofile, hopper, - timeout_unless_slower_valgrind, ) TEST_FILE_DXT1 = "Tests/images/dxt1-rgb-4bbp-noalpha_MipMaps-1.dds" @@ -543,7 +542,6 @@ def test_save_large_file(tmp_path: Path, pixel_format: str, mode: str) -> None: im.save(tmp_path / "img.dds", pixel_format=pixel_format) -@timeout_unless_slower_valgrind(1) @pytest.mark.parametrize( "test_file", [ @@ -553,6 +551,7 @@ def test_save_large_file(tmp_path: Path, pixel_format: str, mode: str) -> None: "Tests/images/timeout-c60a3d7314213624607bfb3e38d551a8b24a7435.dds", ], ) -def test_timeout(test_file) -> None: +def test_not_enough_image_data(test_file: str) -> None: with Image.open(test_file) as im: - im.load() + with pytest.raises(ValueError, match="not enough image data"): + im.load()