[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