From 3a933138ce9273724726efc0df051b8dcf92b7d8 Mon Sep 17 00:00:00 2001 From: Willem Jan Palenstijn Date: Sun, 3 Dec 2017 12:49:11 +0100 Subject: SCI: Avoid buffer overflow in amigamac sound driver By default, frac_t is interpreted as signed. The resulting range isn't large enough to store offsets, so we interpret it as unsigned here instead. Fixes a crash in QfG1/Mac where instrument->loop_size is 49457. --- engines/sci/sound/drivers/amigamac.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'engines/sci') diff --git a/engines/sci/sound/drivers/amigamac.cpp b/engines/sci/sound/drivers/amigamac.cpp index b8b6a32214..22950cb2e7 100644 --- a/engines/sci/sound/drivers/amigamac.cpp +++ b/engines/sci/sound/drivers/amigamac.cpp @@ -34,6 +34,11 @@ namespace Sci { +// We use frac_t to store non-negative offsets that can be larger than 32767 +static uint fracToUInt(frac_t value) { + return ((uint32)value) / (1 << FRAC_BITS); +} + class MidiDriver_AmigaMac : public MidiDriver_Emulated { public: enum { @@ -170,7 +175,7 @@ void MidiDriver_AmigaMac::setEnvelope(Voice *channel, Envelope *envelope, int ph } int MidiDriver_AmigaMac::interpolate(int8 *samples, frac_t offset, uint32 maxOffset, bool isUnsigned) { - uint x = fracToInt(offset); + uint x = fracToUInt(offset); uint x2 = x == maxOffset ? 0 : x + 1; if (isUnsigned) { @@ -272,7 +277,7 @@ void MidiDriver_AmigaMac::playInstrument(int16 *dest, Voice *channel, int count) if (index == count) break; - if ((uint32)fracToInt(channel->offset) >= seg_end) { + if (fracToUInt(channel->offset) >= seg_end) { if (instrument->mode & kModeLoop) { /* Loop the samples */ channel->offset -= intToFrac(seg_end); -- cgit v1.2.3