From f4e5295658fff000379caa122e75c9200205fe20 Mon Sep 17 00:00:00 2001
From: Konstanty Bialkowski <metaplasma@users.sourceforge.net>
Date: Fri, 15 Jul 2011 23:25:23 +1000
Subject: [PATCH] Fix S3M stack overflows (SA45131/B)

---
 libmodplug/src/load_s3m.cpp |   13 ++++++++++---
 1 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/libmodplug/src/load_s3m.cpp b/libmodplug/src/load_s3m.cpp
index edfc255..8678236 100644
--- a/libmodplug/src/load_s3m.cpp
+++ b/libmodplug/src/load_s3m.cpp
@@ -187,11 +187,11 @@
 //---------------------------------------------------------------
 {
 	UINT insnum,patnum,nins,npat;
-	DWORD insfile[128];
+	DWORD insfile[MAX_SAMPLES];
 	WORD ptr[256];
 	BYTE s[1024];
 	DWORD dwMemPos;
-	BYTE insflags[128], inspack[128];
+	BYTE insflags[MAX_SAMPLES], inspack[MAX_SAMPLES];
 	S3MFILEHEADER psfh = *(S3MFILEHEADER *)lpStream;
 
 	psfh.reserved1 = bswapLE16(psfh.reserved1);
@@ -315,7 +315,14 @@
 			Ins[iSmp].nC4Speed = j;
 			insfile[iSmp] = ((DWORD)bswapLE16(*((LPWORD)(s+0x0E)))) << 4;
 			insfile[iSmp] += ((DWORD)(BYTE)s[0x0D]) << 20;
-			if (insfile[iSmp] > dwMemLength) insfile[iSmp] &= 0xFFFF;
+			// offset is invalid - ignore this sample.
+			if (insfile[iSmp] > dwMemLength) insfile[iSmp] = 0;
+			else if (insfile[iSmp]) {
+				// ignore duplicate samples.
+				for (int z=iSmp-1; z>=0; z--)
+					if (insfile[iSmp] == insfile[z])
+						insfile[iSmp] = 0;
+			}
 			if ((Ins[iSmp].nLoopStart >= Ins[iSmp].nLoopEnd) || (Ins[iSmp].nLoopEnd - Ins[iSmp].nLoopStart < 8))
 				Ins[iSmp].nLoopStart = Ins[iSmp].nLoopEnd = 0;
 			Ins[iSmp].nPan = 0x80;
-- 
1.7.0.1

