From c77b7ebd2ad735dc45cb288334e3115d845e14e8 Mon Sep 17 00:00:00 2001 From: dxbjavid Date: Tue, 23 Jun 2026 21:14:31 +0530 Subject: [PATCH] Fix potentially using uninitialised data in PCX image handler Reject truncated reads to avoid uninitialised data. Closes #26624. --- src/common/imagpcx.cpp | 11 +++++++++++ tests/image/image.cpp | 27 +++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/src/common/imagpcx.cpp b/src/common/imagpcx.cpp index d6fff36d39..af8b25f408 100644 --- a/src/common/imagpcx.cpp +++ b/src/common/imagpcx.cpp @@ -173,6 +173,8 @@ int ReadPCX(wxImage *image, wxInputStream& stream) // be at least 5 or higher for 8 bit and 24 bit images). stream.Read(hdr, 128); + if (stream.LastRead() != 128) + return wxPCX_INVFORMAT; if (hdr[HDR_VERSION] < 5) return wxPCX_VERERR; @@ -235,7 +237,14 @@ int ReadPCX(wxImage *image, wxInputStream& stream) if (encoding) RLEdecode(p, bytesperline * nplanes, stream); else + { stream.Read(p, bytesperline * nplanes); + if (stream.LastRead() != bytesperline * nplanes) + { + free(p); + return wxPCX_INVFORMAT; + } + } switch (format) { @@ -273,6 +282,8 @@ int ReadPCX(wxImage *image, wxInputStream& stream) return wxPCX_INVFORMAT; stream.Read(pal, 768); + if (stream.LastRead() != 768) + return wxPCX_INVFORMAT; p = image->GetData(); for (unsigned long k = height * width; k; k--) diff --git a/tests/image/image.cpp b/tests/image/image.cpp index 2f48bee9ef..eac11d5ba8 100644 --- a/tests/image/image.cpp +++ b/tests/image/image.cpp @@ -1560,6 +1560,33 @@ TEST_CASE_METHOD(ImageHandlersInit, "wxImage::BadPCX", "[image][pcx][error]") REQUIRE( !img.LoadFile(mis, wxBITMAP_TYPE_PCX) ); } +TEST_CASE_METHOD(ImageHandlersInit, "wxImage::TruncatedPCXPalette", "[image][pcx][error]") +{ + // A 1x1 8-bit PCX whose 256-colour palette (which follows the 0x0c + // marker at the very end of the file) is truncated. ReadPCX() used to + // read the fixed 768-byte palette without checking how many bytes were + // actually present, so the unread tail of the buffer stayed + // uninitialised and was then copied into the image data and the + // wxImage palette. + unsigned char data[128 + 2 + 1 + 10] = { 0 }; + data[0] = 0x0a; // manufacturer + data[1] = 0x05; // version + data[2] = 0x01; // RLE encoding + data[3] = 0x08; // bits per pixel + // xmin/ymin/xmax/ymax all zero gives a 1x1 image + data[65] = 0x01; // one plane + data[66] = 0x01; // bytes per line + // a single RLE run for one pixel with palette index 255 + data[128] = 0xc1; + data[129] = 0xff; + // palette marker followed by only 10 of the expected 768 palette bytes + data[130] = 0x0c; + + wxMemoryInputStream mis(data, WXSIZEOF(data)); + wxImage img; + REQUIRE( !img.LoadFile(mis, wxBITMAP_TYPE_PCX) ); +} + #endif // wxUSE_PCX TEST_CASE_METHOD(ImageHandlersInit, "wxImage::BadANI", "[image][ani][error]")