[Scummvm-git-logs] scummvm master -> 31cd9eee168cdae6e87c1b836a2bc760f023b804
athrxx
noreply at scummvm.org
Fri Nov 29 23:17:23 UTC 2024
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
31cd9eee16 SCUMM: (IMS/Mac) - fix instrument data handling
Commit: 31cd9eee168cdae6e87c1b836a2bc760f023b804
https://github.com/scummvm/scummvm/commit/31cd9eee168cdae6e87c1b836a2bc760f023b804
Author: athrxx (athrxx at scummvm.org)
Date: 2024-11-30T00:16:08+01:00
Commit Message:
SCUMM: (IMS/Mac) - fix instrument data handling
DOTT and SAM have one instrument with invalid header
data which needs to be handled, to prevent invalid
memory reads. I also added some other checks that the
original interpreters make.
Changed paths:
engines/scumm/imuse/drivers/macintosh.cpp
engines/scumm/players/mac_sound_lowlevel.h
engines/scumm/players/player_mac_new.cpp
diff --git a/engines/scumm/imuse/drivers/macintosh.cpp b/engines/scumm/imuse/drivers/macintosh.cpp
index 801392a9b00..7d4098e0d97 100644
--- a/engines/scumm/imuse/drivers/macintosh.cpp
+++ b/engines/scumm/imuse/drivers/macintosh.cpp
@@ -139,7 +139,6 @@ private:
void *_timerParam;
Common::TimerManager::TimerProc _timerProc;
- const byte _loopstLim;
const byte _version;
};
@@ -327,7 +326,7 @@ void DeviceChannel::recalcFrequency() {
IMSMacSoundSystem::IMSMacSoundSystem(Audio::Mixer *mixer, byte version) : VblTaskClientDriver(), _mixer(mixer), _macstr(nullptr), _sdrv(nullptr), _vblTskProc(this, &VblTaskClientDriver::vblCallback),
_musicChan(0), _sfxChan(0), _quality(22), _feedBufferSize(1024), _channels(nullptr), _timerParam(nullptr), _timerProc(nullptr), _pitchTable(nullptr),
- _ampTable(nullptr), _mixTable(nullptr), _numChannels(version ? 12 : 8), _defaultInstrID(0), _version(version), _loopstLim(version ? 10 : 12), _stereo(false) {
+ _ampTable(nullptr), _mixTable(nullptr), _numChannels(version ? 12 : 8), _defaultInstrID(0), _version(version), _stereo(false) {
_pitchTable = new uint32[128]();
assert(_pitchTable);
_channels = new DeviceChannel*[_numChannels];
@@ -464,14 +463,13 @@ void IMSMacSoundSystem::noteOn(const ChanControlNode *node) {
c->rate = s->rate;
c->smpBuffStart = s->data.get();
c->smpBuffEnd = c->smpBuffStart + s->len;
- if ((int32)s->loopst >= (int32)s->loopend - _loopstLim) {
+ if ((_version == 0 && (int32)s->loopst >= (int32)s->loopend - 12) || (_version > 0 && (!s->loopst || !s->loopend || node->rhythmPart || (int32)s->loopst > (int32)s->len - 10))) {
c->loopStart = nullptr;
c->loopEnd = c->smpBuffEnd;
} else {
c->loopStart = c->smpBuffStart + s->loopst;
c->loopEnd = c->smpBuffStart + s->loopend;
}
-
c->pitch = (node->note << 7) + node->pitchBend;
c->mute = c->release = false;
c->end = c->loopEnd;
@@ -833,7 +831,9 @@ bool NewMacSoundSystem::loadInstruments(const char *const *fileNames, int numFil
_smpResources.clear();
const byte *s = buff;
for (uint i = 0; i < num; ++i) {
- _smpResources.push_back(Common::SharedPtr<MacSndResource>(new MacSndResource(READ_BE_UINT16(s + 2), buff + READ_BE_UINT32(s + 4))));
+ uint32 offset = READ_BE_UINT32(s + 4);
+ uint32 resSize = (i < num - 1 ? READ_BE_UINT32(s + 12) : size) - offset;
+ _smpResources.push_back(Common::SharedPtr<MacSndResource>(new MacSndResource(READ_BE_UINT16(s + 2), buff + offset, resSize)));
s += 8;
}
delete[] buff;
diff --git a/engines/scumm/players/mac_sound_lowlevel.h b/engines/scumm/players/mac_sound_lowlevel.h
index 1b1059749ce..3ffd96cfaf5 100644
--- a/engines/scumm/players/mac_sound_lowlevel.h
+++ b/engines/scumm/players/mac_sound_lowlevel.h
@@ -243,7 +243,7 @@ public:
// Construct from Mac resource stream
MacSndResource(uint32 id, Common::SeekableReadStream *&in, Common::String &&name);
// Construct from Mac sound data buffer
- MacSndResource(uint32 id, const byte *in);
+ MacSndResource(uint32 id, const byte *in, uint32 size);
~MacSndResource() {}
const MacLowLevelPCMDriver::PCMSound *data() const { return &_snd; }
uint32 id() const { return _id; }
diff --git a/engines/scumm/players/player_mac_new.cpp b/engines/scumm/players/player_mac_new.cpp
index 8f6ee54154d..61386d15ab7 100644
--- a/engines/scumm/players/player_mac_new.cpp
+++ b/engines/scumm/players/player_mac_new.cpp
@@ -1265,13 +1265,23 @@ MacSndResource::MacSndResource(uint32 id, Common::SeekableReadStream *&in, Commo
_snd.enc = in->readByte();
_snd.baseFreq = in->readByte();
- byte *buff = new byte[_snd.len];
- if (in->read(buff, _snd.len) != _snd.len)
+ uint32 realSize = in->size() - in->pos();
+ if (_snd.len > realSize) {
+ debug(6, "%s(): Invalid data in resource '%d' - Fixing out of range samples count (samples buffer size '%d', samples count '%d')", __FUNCTION__, id, realSize, _snd.len);
+ _snd.len = realSize;
+ }
+ if ((int32)_snd.loopend > (int32)realSize) {
+ debug(6, "%s(): Invalid data in resource '%d' - Fixing out of range loop end (samples buffer size '%d', loop end '%d')", __FUNCTION__, id, realSize, _snd.loopend);
+ _snd.loopend = realSize;
+ }
+
+ byte *buff = new byte[realSize];
+ if (in->read(buff, realSize) != realSize)
error("%s(): Data error", __FUNCTION__);
_snd.data = Common::SharedPtr<const byte>(buff, Common::ArrayDeleter<const byte>());
}
-MacSndResource::MacSndResource(uint32 id, const byte *in) : _id(id) {
+MacSndResource::MacSndResource(uint32 id, const byte *in, uint32 size) : _id(id) {
in += 4;
_snd.len = READ_BE_UINT32(in);
in += 4;
@@ -1284,8 +1294,18 @@ MacSndResource::MacSndResource(uint32 id, const byte *in) : _id(id) {
_snd.enc = *in++;
_snd.baseFreq = *in++;
- byte *buff = new byte[_snd.len];
- memcpy(buff, in, _snd.len);
+ size -= 22;
+ if (_snd.len > size) {
+ debug("%s(): Invalid data in resource '%d' - Fixing out of range samples count (samples buffer size '%d', samples count '%d')", __FUNCTION__, id, size, _snd.len);
+ _snd.len = size;
+ }
+ if ((int32)_snd.loopend > (int32)size) {
+ debug("%s(): Invalid data in resource '%d' - Fixing out of range loop end (samples buffer size '%d', loop end '%d')", __FUNCTION__, id, size, _snd.loopend);
+ _snd.loopend = size;
+ }
+
+ byte *buff = new byte[size];
+ memcpy(buff, in, size);
_snd.data = Common::SharedPtr<const byte>(buff, Common::ArrayDeleter<const byte>());
}
More information about the Scummvm-git-logs
mailing list