From 49a4dbee56bca3737a26f91ae32b6a6d6cca6f8a Mon Sep 17 00:00:00 2001 From: dxbjavid Date: Fri, 22 May 2026 22:56:52 +0530 Subject: [PATCH] Stop reading past wxCharBuffer end on unterminated XPM quote The quote-stripping loop in wxXPMDecoder::ReadFile() sets p = q + 1 after strncpy(). If the closing " was missing, q stopped at the buffer terminator, so p ended up one past it and the outer for-loop's p++ then dereferenced two bytes off the end of the wxCharBuffer. Mirror the already-existing /*-comment treatment and break out of the loop when *q == '\0'. Closes #26499. --- src/common/xpmdecod.cpp | 6 ++++++ tests/image/image.cpp | 16 ++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/common/xpmdecod.cpp b/src/common/xpmdecod.cpp index 6953cb3066..0d3221306d 100644 --- a/src/common/xpmdecod.cpp +++ b/src/common/xpmdecod.cpp @@ -190,6 +190,12 @@ wxImage wxXPMDecoder::ReadFile(wxInputStream& stream) for (q = p + 1; *q != '\0'; q++) if (*q == '"') break; + + // unterminated quoted string: stop processing rather than reading + // past the end of the buffer when the outer loop next advances p. + if (*q == '\0') + break; + strncpy(xpm_buffer + i, p + 1, q - p - 1); i += q - p - 1; xpm_buffer[i++] = '\n'; diff --git a/tests/image/image.cpp b/tests/image/image.cpp index c64e160477..79dd80ba9f 100644 --- a/tests/image/image.cpp +++ b/tests/image/image.cpp @@ -1361,6 +1361,22 @@ TEST_CASE_METHOD(ImageHandlersInit, "wxImage::BadXPM", "[image][xpm][error]") REQUIRE( !img.LoadFile(mis, wxBITMAP_TYPE_XPM) ); } +TEST_CASE_METHOD(ImageHandlersInit, "wxImage::BadXPMUnterminatedQuote", + "[image][xpm][error]") +{ + // A payload whose final " is never closed: the quote-stripping loop in + // wxXPMDecoder::ReadFile() advanced p past the buffer terminator after + // strncpy() and then dereferenced one byte further on the next outer + // for-loop iteration, reading past the end of the wxCharBuffer. + static const unsigned char data[] = + { + 0x22,0x61,0x62,0x63, + }; + wxMemoryInputStream mis(data, WXSIZEOF(data)); + wxImage img; + REQUIRE( !img.LoadFile(mis, wxBITMAP_TYPE_XPM) ); +} + #endif // wxUSE_XPM #if wxUSE_IFF