From 7849f78b48b5a2e842294563a21da67823a63a0d Mon Sep 17 00:00:00 2001 From: Johannes Schultz Date: Sat, 11 May 2024 20:11:21 +0000 Subject: [PATCH] Merged revision(s) 20693 from trunk/OpenMPT: [Imp] XM: Reject files with impossible pattern header. [Imp] XM: Speed up decoding early if pattern data cannot be read, ignore patterns > MAX_PATTERNS for decoding. ........ git-svn-id: https://source.openmpt.org/svn/openmpt/branches/OpenMPT-1.30@20762 56274372-70c3-4bfc-bfc3-4c3a0b034d27 --- soundlib/Load_xm.cpp | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/soundlib/Load_xm.cpp b/soundlib/Load_xm.cpp index a1909426328..9745c1d629e 100644 --- a/soundlib/Load_xm.cpp +++ b/soundlib/Load_xm.cpp @@ -244,18 +244,16 @@ static void ReadXMPatterns(FileReader &file, const XMFileHeader &fileHeader, CSo for(PATTERNINDEX pat = 0; pat < fileHeader.patterns; pat++) { FileReader::off_t curPos = file.GetPosition(); - uint32 headerSize = file.ReadUint32LE(); - file.Skip(1); // Pack method (= 0) - - ROWINDEX numRows = 64; + const uint32 headerSize = file.ReadUint32LE(); + if(headerSize < 8 || !file.CanRead(headerSize - 4)) + break; + file.Skip(1); // Pack method (= 0) + ROWINDEX numRows; if(fileHeader.version == 0x0102) - { numRows = file.ReadUint8() + 1; - } else - { + else numRows = file.ReadUint16LE(); - } // A packed size of 0 indicates a completely empty pattern. const uint16 packedSize = file.ReadUint16LE(); @@ -268,10 +266,8 @@ static void ReadXMPatterns(FileReader &file, const XMFileHeader &fileHeader, CSo file.Seek(curPos + headerSize); FileReader patternChunk = file.ReadChunk(packedSize); - if(!sndFile.Patterns.Insert(pat, numRows) || packedSize == 0) - { + if(pat >= MAX_PATTERNS || !sndFile.Patterns.Insert(pat, numRows) || packedSize == 0) continue; - } enum PatternFlags { @@ -287,6 +283,9 @@ static void ReadXMPatterns(FileReader &file, const XMFileHeader &fileHeader, CSo for(auto &m : sndFile.Patterns[pat]) { + if(!file.CanRead(1)) + break; + uint8 info = patternChunk.ReadUint8(); uint8 vol = 0; @@ -1217,7 +1216,7 @@ bool CSoundFile::SaveXM(std::ostream &f, bool compatibilityExport) if(!p->IsEmpty()) emptyPattern = false; - // Apparently, completely empty patterns are loaded as empty 64-row patterns in FT2, regardless of their original size. + // Completely empty patterns are loaded as empty 64-row patterns in FT2, regardless of their original size. // We have to avoid this, so we add a "break to row 0" command in the last row. if(j == 1 && emptyPattern && numRows != 64) {