Skip to content

Commit

Permalink
Merged revision(s) 20538 from trunk/OpenMPT:
Browse files Browse the repository at this point in the history
[Mod] M15: The heuristics in r20524 were a bit too loose, also identifying some GMC files as SoundTracker modules. Tighten the song title check again to previous values, but ignore it if a sufficent amount of sample headers has "real-looking" sample names (starting with a disk name like st-01:...).
........


git-svn-id: https://source.openmpt.org/svn/openmpt/branches/OpenMPT-1.30@20540 56274372-70c3-4bfc-bfc3-4c3a0b034d27
  • Loading branch information
sagamusix committed Apr 8, 2024
1 parent 170dea4 commit d106319
Showing 1 changed file with 18 additions and 7 deletions.
25 changes: 18 additions & 7 deletions soundlib/Load_mod.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,11 @@ struct MODSampleHeader
+ ((loopStart > length * 2) ? 1 : 0);
}

bool HasDiskName() const
{
return (!memcmp(name, "st-", 3) || !memcmp(name, "ST-", 3)) && name[5] == ':';
}

// Suggested threshold for rejecting invalid files based on cumulated score returned by GetInvalidByteScore
static constexpr uint32 INVALID_BYTE_THRESHOLD = 40;

Expand Down Expand Up @@ -1370,15 +1375,13 @@ static bool ValidateHeader(const M15FileHeaders &fileHeaders)
// However, there are quite a few SoundTracker modules in the wild with random
// characters. To still be able to distguish them from other formats, we just reject
// files with *too* many bogus characters. Arbitrary threshold: 48 bogus characters in total
// or more than 11 invalid characters just in the title alone (just enough to make scramble_2.mod load).
uint32 invalidChars = CountInvalidChars(fileHeaders.songname);
if(invalidChars > 11)
{
return false;
}
// or more than 5 invalid characters just in the title alone
uint32 invalidCharsInTitle = CountInvalidChars(fileHeaders.songname);
uint32 invalidChars = invalidCharsInTitle;

SmpLength totalSampleLen = 0;
uint8 allVolumes = 0;
uint8 diskNameCount = 0;

for(SAMPLEINDEX smp = 0; smp < 15; smp++)
{
Expand All @@ -1389,6 +1392,8 @@ static bool ValidateHeader(const M15FileHeaders &fileHeaders)
// schmokk.mod has a non-zero value here but it should not be treated as finetune
if(sampleHeader.finetune != 0)
invalidChars += 16;
if(sampleHeader.HasDiskName())
diskNameCount++;

// Sanity checks - invalid character count adjusted for ata.mod (MD5 937b79b54026fa73a1a4d3597c26eace, SHA1 3322ca62258adb9e0ae8e9afe6e0c29d39add874)
if(invalidChars > 48
Expand All @@ -1402,6 +1407,12 @@ static bool ValidateHeader(const M15FileHeaders &fileHeaders)
allVolumes |= sampleHeader.volume;
}

// scramble_2.mod has a lot of garbage in the song title, but it has lots of sample names starting with st-01, so we consider those to be more important than the garbage bytes.
if(invalidCharsInTitle > 5 && diskNameCount < 4)
{
return false;
}

// Reject any files with no (or only silent) samples at all, as this might just be a random binary file (e.g. ID3 tags with tons of padding)
if(totalSampleLen == 0 || allVolumes == 0)
{
Expand Down Expand Up @@ -1507,7 +1518,7 @@ bool CSoundFile::ReadM15(FileReader &file, ModLoadingFlags loadFlags)

totalSampleLen += mptSmp.nLength;

if(m_szNames[smp][0] && ((memcmp(m_szNames[smp].buf, "st-", 3) && memcmp(m_szNames[smp].buf, "ST-", 3)) || m_szNames[smp][5] != ':'))
if(m_szNames[smp][0] && sampleHeader.HasDiskName())
{
// Ultimate Soundtracker 1.8 and D.O.C. SoundTracker IX always have sample names containing disk names.
hasDiskNames = false;
Expand Down

0 comments on commit d106319

Please sign in to comment.