Picking up this topic again... recently I have changed my MO3 decoder to decompress data on-the-fly. That way, even if the music data is claimed to be very large, only as much data as is required to read the MO3 structures will actually be decompressed. That makes it a bit harder to force the application to waste memory, but there are still a few way to do that, and I think they could be mitigated by defining a few limits for certain problematic structures:
- Track data length: This one is easy. It's encoded as a uint32 value, but we can actually establish an upper limit of about 2MB per track (65535 rows containing at most 15 events, that's 2,031,585 bytes). Hence, this would only need to be verified in the decoder, the encoder cannot produce a track that is too big.
- String lengths: This one is a bit more tricky. A one gigabyte long string containing just "AAAAAAAAAAAAAAAAAAAAAAAAAAA...." with no null byte anywhere can be encoded in just a few bytes. Since the song name is the first field in the music data, you cannot even verify any of the other header structures if they make sense without decompressing that string. Maybe we can say that any song, instrument or sample name longer than 1024 characters should be considered invalid (that's probably long enough to cover any sensible format extensions), and the song message should not be longer than 1024 * 1024 characters. Could also increase it to 8KB and 8MB respectively to be
really future-proof.
- Plugin chunks: This one is tricky because there are some plugins out there which save their plugin chunks in a really wasteful way. Chunk sizes beyond 1MB are not unheard of. But I would guess that as with instrument names, a limit like 64MB would be well beyond any in-the-wild chunk sizes, and would still prevent some wasteful memory allocation to happen (but probably not enough, as 250 plugins with 64 MB chunks each would still be bigger than the physical maximum size of the uncompressed music chunk anyway).
- The new chunk extensions at the end of the file: As there can be an arbitrary amount of them, this one is again very tricky. Apart from establishing a similar limit as for plugin chunks, I'm not sure what to do here.
What do you think? Would adding any of those limitations to the MO3 encoder make sense? Obviously some of those limits are not really applicable to the MO3 encoder right now (there's no file formats it supports that have song titles that long, for instance) - but I think it would be good to just have a common definition of what is considered to be a valid MO3 file and what isn't.
In general limiting the size of the LZ window is probably also not going to work when existing real-world modules have to be accounted for - even if the back window was limited to 16K, a file smaller than 1MB could still produce a 2GB output, I think. So disallowing some of those music data structures to even grow that big might be the better approach.