Skip to content

Commit

Permalink
Merged revision(s) 20564 from trunk/OpenMPT:
Browse files Browse the repository at this point in the history
[Imp] M15: The heuristics in r20524 were still too loose, also identifying completely unrelated file types. We validate the pattern data much more thoroughly now and check that there are no weird period values. There's one extremely damaged M15 file that will no longer play, but it was not particularly listenable before this change (even sample length were incorrect, lots of pattern garbage, etc.), so it's no big loss.
........


git-svn-id: https://source.openmpt.org/svn/openmpt/branches/OpenMPT-1.30@20566 56274372-70c3-4bfc-bfc3-4c3a0b034d27
  • Loading branch information
sagamusix committed Apr 11, 2024
1 parent dec9ab1 commit 1c154f3
Showing 1 changed file with 17 additions and 5 deletions.
22 changes: 17 additions & 5 deletions soundlib/Load_mod.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -534,16 +534,28 @@ static uint32 ReadSample(FileReader &file, MODSampleHeader &sampleHeader, ModSam


// Count malformed bytes in MOD pattern data
static uint32 CountMalformedMODPatternData(const MODPatternData &patternData, const bool allow31Samples)
static uint32 CountMalformedMODPatternData(const MODPatternData &patternData, const bool extendedFormat)
{
const uint8 mask = allow31Samples ? 0xE0 : 0xF0;
const uint8 mask = extendedFormat ? 0xE0 : 0xF0;
uint32 malformedBytes = 0;
for(const auto &row : patternData)
{
for(const auto &data : row)
{
if(data[0] & mask)
malformedBytes++;
if(!extendedFormat)
{
const uint16 period = (((static_cast<uint16>(data[0]) & 0x0F) << 8) | data[1]);
if(period && period != 0xFFF)
{
// Allow periods to deviate by +/-1 as found in some files
const auto CompareFunc = [](uint16 l, uint16 r) { return l > (r + 1); };
const auto PeriodTable = mpt::as_span(ProTrackerPeriodTable).subspan(24, 36);
if(!std::binary_search(PeriodTable.begin(), PeriodTable.end(), period, CompareFunc))
malformedBytes += 2;
}
}
}
}
return malformedBytes;
Expand All @@ -552,12 +564,12 @@ static uint32 CountMalformedMODPatternData(const MODPatternData &patternData, co

// Check if number of malformed bytes in MOD pattern data exceeds some threshold
template <typename TFileReader>
static bool ValidateMODPatternData(TFileReader &file, const uint32 threshold, const bool allow31Samples)
static bool ValidateMODPatternData(TFileReader &file, const uint32 threshold, const bool extendedFormat)
{
MODPatternData patternData;
if(!file.Read(patternData))
return false;
return CountMalformedMODPatternData(patternData, allow31Samples) <= threshold;
return CountMalformedMODPatternData(patternData, extendedFormat) <= threshold;
}


Expand Down Expand Up @@ -1614,7 +1626,7 @@ bool CSoundFile::ReadM15(FileReader &file, ModLoadingFlags loadFlags)
// "operation wolf" soundtrack have 15 patterns for several songs, but the last few patterns are just garbage.
// Apart from those hidden patterns, the files play fine.
// Example: operation wolf - wolf1.mod (MD5 739acdbdacd247fbefcac7bc2d8abe6b, SHA1 e6b4813daacbf95f41ce9ec3b22520a2ae07eed8)
if(illegalBytes > 512)
if(illegalBytes > std::max(512u, numPatterns * 128u))
return false;
}
for(ROWINDEX row = 0; row < 64; row++)
Expand Down

0 comments on commit 1c154f3

Please sign in to comment.