aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS3
-rw-r--r--engines/sword1/sound.cpp16
2 files changed, 14 insertions, 5 deletions
diff --git a/NEWS b/NEWS
index 83c743db35..6207a59030 100644
--- a/NEWS
+++ b/NEWS
@@ -38,6 +38,9 @@ For a more comprehensive changelog for the latest experimental SVN code, see:
BASS:
- Fixed character spacing in LINC terminals in floppy version v0.0303
+ Broken Sword 1:
+ - Fixed speech-related crashes.
+
Broken Sword 2:
- More robust handling of the optional startup.inf file.
diff --git a/engines/sword1/sound.cpp b/engines/sword1/sound.cpp
index c2576ee7d4..f699a4c475 100644
--- a/engines/sword1/sound.cpp
+++ b/engines/sword1/sound.cpp
@@ -260,24 +260,30 @@ int16 *Sound::uncompressSpeech(uint32 index, uint32 cSize, uint32 *size) {
uint32 srcPos = headerPos >> 1;
cSize /= 2;
uint32 dstPos = 0;
- /* alloc 200 additional bytes, as the demo sometimes has ASCII junk
- at the end of the wave data */
- int16 *dstData = (int16*)malloc(resSize * 2 + 200);
- while (srcPos < cSize) {
+ int16 *dstData = (int16*)malloc(resSize * 2);
+ int32 samplesLeft = resSize;
+ while (srcPos < cSize && samplesLeft > 0) {
int16 length = (int16)READ_LE_UINT16(srcData + srcPos);
srcPos++;
if (length < 0) {
length = -length;
+ if (length > samplesLeft)
+ length = samplesLeft;
for (uint16 cnt = 0; cnt < (uint16)length; cnt++)
dstData[dstPos++] = srcData[srcPos];
srcPos++;
} else {
+ if (length > samplesLeft)
+ length = samplesLeft;
memcpy(dstData + dstPos, srcData + srcPos, length * 2);
dstPos += length;
srcPos += length;
}
+ samplesLeft -= length;
+ }
+ if (samplesLeft > 0) {
+ memset(dstData + dstPos, 0, samplesLeft * 2);
}
- assert(dstPos < (uint32)resSize + 100);
if (_cowMode == CowDemo) // demo has wave output size embedded in the compressed data
*(uint32*)dstData = 0;
free(fBuf);