Author: sagamusix
Date: Sat May 11 23:36:49 2024
New Revision: 20781
URL: https://source.openmpt.org/browse/openmpt/?op=revision&rev=20781
Log:
Merged revision(s) 20780 from branches/OpenMPT-1.31:
Merged revision(s) 20736 from trunk/OpenMPT:
[Imp] STK: Allow romantic.stk to load, which has a sample longer than 74KB.
[Imp] STK: Also allow files to load that have garbage in the song title, but whose sample names are properly null-terminated non-empty ASCII strings. Fixes STK.Sharks-NewIntro.
........
........
Modified:
branches/OpenMPT-1.30/ (props changed)
branches/OpenMPT-1.30/soundlib/Load_mod.cpp
Modified: branches/OpenMPT-1.30/soundlib/Load_mod.cpp
==============================================================================
--- branches/OpenMPT-1.30/soundlib/Load_mod.cpp Sat May 11 23:35:36 2024 (r20780)
+++ branches/OpenMPT-1.30/soundlib/Load_mod.cpp Sat May 11 23:36:49 2024 (r20781)
@@ -1355,6 +1355,34 @@
}
+enum class NameClassification
+{
+ Empty,
+ ValidASCII,
+ Invalid,
+};
+
+// Check if a name is a valid null-terminated ASCII string with no garbage after the null terminator, or if it's empty
+static NameClassification ClassifyName(const mpt::span<const char> name) noexcept
+{
+ bool foundNull = false, foundNormal = false;
+ for(auto c : name)
+ {
+ if(c > 0 && c < ' ')
+ return NameClassification::Invalid;
+ if(c == 0)
+ foundNull = true;
+ else if(foundNull)
+ return NameClassification::Invalid;
+ else
+ foundNormal = true;
+ }
+ if(!foundNull)
+ return NameClassification::Invalid;
+ return foundNormal ? NameClassification::ValidASCII : NameClassification::Empty;
+}
+
+
// We'll have to do some heuristic checks to find out whether this is an old Ultimate Soundtracker module
// or if it was made with the newer Soundtracker versions.
// Thanks for Fraggie for this information! (https://www.un4seen.com/forum/?topic=14471.msg100829#msg100829)
@@ -1393,7 +1421,8 @@
SmpLength totalSampleLen = 0;
uint8 allVolumes = 0;
- uint8 diskNameCount = 0;
+ uint8 validNameCount = 0;
+ bool invalidNames = false;
for(SAMPLEINDEX smp = 0; smp < 15; smp++)
{
@@ -1404,13 +1433,16 @@
// 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++;
+ if(const auto nameType = ClassifyName(sampleHeader.name); nameType == NameClassification::ValidASCII)
+ validNameCount++;
+ else if(nameType == NameClassification::Invalid)
+ invalidNames = true;
// Sanity checks - invalid character count adjusted for ata.mod (MD5 937b79b54026fa73a1a4d3597c26eace, SHA1 3322ca62258adb9e0ae8e9afe6e0c29d39add874)
+ // Sample length adjusted for romantic.stk which has a (valid) sample of length 72222
if(invalidChars > 48
|| sampleHeader.volume > 64
- || sampleHeader.length > 32768)
+ || sampleHeader.length > 37000)
{
return false;
}
@@ -1419,8 +1451,8 @@
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)
+ // scramble_2.mod has a lot of garbage in the song title, but it has lots of properly-formatted sample names, so we consider those to be more important than the garbage bytes.
+ if(invalidCharsInTitle > 5 && (validNameCount < 4 || invalidNames))
{
return false;
}
|