[frameworks/kimageformats] src/imageformats: rgb: reject RLE start offsets that underflow the raster data
Aljo Joby <[email protected]>
| Newsgroups | gmane.comp.kde.cvs |
|---|---|
| Message-ID | <[email protected]> |
Git commit 09452b0964d7ccf1b370a0b07973acf810959139 by Aljo Joby.
Committed on 14/08/2026 at 15:33.
Pushed by aacid into branch 'master'.
rgb: reject RLE start offsets that underflow the raster data
The start table is stored as file offsets. We subtract the
header+table size to get an index into the remaining data.
If the file offset is smaller than that, the subtract wraps
and the later start+length check can wrap too.
Drop the file instead of walking off the buffer.
M +9 -3 src/imageformats/rgb.cpp
https://invent.kde.org/frameworks/kimageformats/-/commit/09452b0964d7ccf1b370a0b07973acf810959139
diff --git a/src/imageformats/rgb.cpp b/src/imageformats/rgb.cpp
index 1052fac4..17bda896 100644
--- a/src/imageformats/rgb.cpp
+++ b/src/imageformats/rgb.cpp
@@ -314,6 +314,8 @@ bool SGIImagePrivate::readImage(QImage &img)
_numrows = _ysize * _zsize;
if (_rle) {
+ // start table holds file offsets; raster data follows header + both tables
+ const quint32 dataOff = 512 + _numrows * 2 * sizeof(quint32);
uint l;
_starttab = new (std::nothrow) quint32[_numrows];
if (_starttab == nullptr) {
@@ -321,7 +323,10 @@ bool SGIImagePrivate::readImage(QImage &img)
}
for (l = 0; !_stream.atEnd() && l < _numrows; l++) {
_stream >> _starttab[l];
- _starttab[l] -= 512 + _numrows * 2 * sizeof(quint32);
+ if (_starttab[l] < dataOff) {
+ return false;
+ }
+ _starttab[l] -= dataOff;
if (_stream.status() != QDataStream::Ok) {
return false;
}
@@ -353,9 +358,10 @@ bool SGIImagePrivate::readImage(QImage &img)
// sanity check
if (_rle) {
+ const uint dataSize = uint(_data.size());
for (uint o = 0; o < _numrows; o++) {
- // don't change to greater-or-equal!
- if (_starttab[o] + _lengthtab[o] > (uint)_data.size()) {
+ // don't add start+length: uint32 wrap would pass a corrupt file
+ if (_starttab[o] > dataSize || _lengthtab[o] > dataSize - _starttab[o]) {
// qCDebug(LOG_RGBPLUGIN) << "image corrupt (sanity check failed)";
return false;
}