[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [17035] trunk/blender/intern/SoundSystem: fix for [#17783] problem when packing wav

Campbell Barton ideasman42 at gmail.com
Sun Oct 12 02:51:55 CEST 2008


Revision: 17035
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=17035
Author:   campbellbarton
Date:     2008-10-12 02:51:55 +0200 (Sun, 12 Oct 2008)

Log Message:
-----------
fix for [#17783] problem when packing wav
"data" is aligned differently in this wave file and the buffer was read past its allocated length.

Fix this by searching for the buffer in increments of 2 (this finds the "data" for the wav file)
added a check not to allow the search to go past the buffer length, so corrupt wave files should not crash.

Modified Paths:
--------------
    trunk/blender/intern/SoundSystem/SND_Utils.h
    trunk/blender/intern/SoundSystem/fmod/SND_FmodDevice.cpp
    trunk/blender/intern/SoundSystem/intern/SND_Utils.cpp

Modified: trunk/blender/intern/SoundSystem/SND_Utils.h
===================================================================
--- trunk/blender/intern/SoundSystem/SND_Utils.h	2008-10-12 00:41:28 UTC (rev 17034)
+++ trunk/blender/intern/SoundSystem/SND_Utils.h	2008-10-12 00:51:55 UTC (rev 17035)
@@ -97,8 +97,8 @@
 extern unsigned int SND_GetNumberOfChannels(void* sample);
 extern unsigned int SND_GetSampleRate(void* sample);
 extern unsigned int SND_GetBitRate(void* sample);
-extern unsigned int SND_GetNumberOfSamples(void* sample);
-extern unsigned int SND_GetHeaderSize(void* sample);
+extern unsigned int SND_GetNumberOfSamples(void* sample, int sample_length);
+extern unsigned int SND_GetHeaderSize(void* sample, int sample_length);
 extern unsigned int SND_GetExtraChunk(void* sample);
 
 extern void SND_GetSampleInfo(signed char* sample, SND_WaveSlot* waveslot);

Modified: trunk/blender/intern/SoundSystem/fmod/SND_FmodDevice.cpp
===================================================================
--- trunk/blender/intern/SoundSystem/fmod/SND_FmodDevice.cpp	2008-10-12 00:41:28 UTC (rev 17034)
+++ trunk/blender/intern/SoundSystem/fmod/SND_FmodDevice.cpp	2008-10-12 00:51:55 UTC (rev 17035)
@@ -162,7 +162,7 @@
 						int numberofchannels = SND_GetNumberOfChannels(memlocation);
 						int samplerate = SND_GetSampleRate(memlocation);
 						int bitrate = SND_GetBitRate(memlocation);
-						int numberofsamples = SND_GetNumberOfSamples(memlocation);
+						int numberofsamples = SND_GetNumberOfSamples(memlocation, size);
 						
 						waveslot->SetFileSize(size);
 						waveslot->SetData(memlocation);

Modified: trunk/blender/intern/SoundSystem/intern/SND_Utils.cpp
===================================================================
--- trunk/blender/intern/SoundSystem/intern/SND_Utils.cpp	2008-10-12 00:41:28 UTC (rev 17034)
+++ trunk/blender/intern/SoundSystem/intern/SND_Utils.cpp	2008-10-12 00:51:55 UTC (rev 17035)
@@ -285,10 +285,9 @@
 
 
 /* gets the length of the actual sample data (without the header) */
-unsigned int SND_GetNumberOfSamples(void* sample)
+unsigned int SND_GetNumberOfSamples(void* sample, int sample_length)
 {
 	unsigned int chunklength, length = 0, offset = 16;
-	char data[4];
 	
 	if (CheckSample(sample))
 	{
@@ -297,14 +296,15 @@
 		if (SND_fEndian == SND_endianBig) SWITCH_INT(chunklength);
 
 		offset = offset + chunklength + 4;
-		memcpy(data, ((char*)sample) + offset, 4);
 
 		/* This seems very unsafe, what if data is never found (f.i. corrupt file)... */
 		// lets find "data"
-		while (memcmp(data, "data", 4))
+		while (memcmp(((char*)sample) + offset, "data", 4))
 		{
-			offset += 4;
-			memcpy(data, ((char*)sample) + offset, 4);
+			offset += 2;
+			
+			if (offset+4 > sample_length) /* save us from crashing */
+				return 0;
 		}
 		offset += 4;
 		memcpy(&length, ((char*)sample) + offset, 4);
@@ -319,10 +319,9 @@
 
 
 /* gets the size of the entire header (file - sampledata) */
-unsigned int SND_GetHeaderSize(void* sample)
+unsigned int SND_GetHeaderSize(void* sample, int sample_length)
 {
 	unsigned int chunklength, headersize = 0, offset = 16;
-	char data[4];
 	
 	if (CheckSample(sample))
 	{
@@ -330,13 +329,14 @@
 		/* This was endian unsafe. See top of the file for the define. */
 		if (SND_fEndian == SND_endianBig) SWITCH_INT(chunklength);
 		offset = offset + chunklength + 4;
-		memcpy(data, ((char*)sample) + offset, 4);
 
 		// lets find "data"
-		while (memcmp(data, "data", 4))
+		while (memcmp(((char*)sample) + offset, "data", 4))
 		{
-			offset += 4;
-			memcpy(data, ((char*)sample) + offset, 4);
+			offset += 2;
+			
+			if (offset+4 > sample_length) /* save us from crashing */
+				return 0;
 		}
 		headersize = offset + 8;
 	}
@@ -382,58 +382,60 @@
 	if (CheckSample(sample))
 	{
 		memcpy(&fileheader, sample, sizeof(WavFileHeader));
-		fileheader.size = SND_GetHeaderSize(sample);
-		sample += sizeof(WavFileHeader);
-		fileheader.size = ((fileheader.size+1) & ~1) - 4;
+		fileheader.size = SND_GetHeaderSize(sample, waveslot->GetFileSize());
+		if (fileheader.size) { /* this may fail for corrupt files */
+			sample += sizeof(WavFileHeader);
+			fileheader.size = ((fileheader.size+1) & ~1) - 4;
 
-		while ((fileheader.size > 0) && (memcpy(&chunkheader, sample, sizeof(WavChunkHeader))))
-		{
-			sample += sizeof(WavChunkHeader);
-			if (!memcmp(chunkheader.id, "fmt ", 4))
+			while ((fileheader.size > 0) && (memcpy(&chunkheader, sample, sizeof(WavChunkHeader))))
 			{
-				memcpy(&fmtheader, sample, sizeof(WavFmtHeader));
-				waveslot->SetSampleFormat(fmtheader.format);
+				sample += sizeof(WavChunkHeader);
+				if (!memcmp(chunkheader.id, "fmt ", 4))
+				{
+					memcpy(&fmtheader, sample, sizeof(WavFmtHeader));
+					waveslot->SetSampleFormat(fmtheader.format);
 
-				if (fmtheader.format == 0x0001)
+					if (fmtheader.format == 0x0001)
+					{
+						waveslot->SetNumberOfChannels(fmtheader.numberofchannels);
+						waveslot->SetBitRate(fmtheader.bitrate);
+						waveslot->SetSampleRate(fmtheader.samplerate);
+						sample += chunkheader.size;
+					} 
+					else
+					{
+						memcpy(&fmtexheader, sample, sizeof(WavFmtExHeader));
+						sample += chunkheader.size;
+					}
+				}
+				else if (!memcmp(chunkheader.id, "data", 4))
 				{
-					waveslot->SetNumberOfChannels(fmtheader.numberofchannels);
-					waveslot->SetBitRate(fmtheader.bitrate);
-					waveslot->SetSampleRate(fmtheader.samplerate);
-					sample += chunkheader.size;
-				} 
-				else
+					if (fmtheader.format == 0x0001)
+					{
+						waveslot->SetNumberOfSamples(chunkheader.size);
+						sample += chunkheader.size;
+					}
+					else if (fmtheader.format == 0x0011)
+					{
+						//IMA ADPCM
+					}
+					else if (fmtheader.format == 0x0055)
+					{
+						//MP3 WAVE
+					}
+				}
+				else if (!memcmp(chunkheader.id, "smpl", 4))
 				{
-					memcpy(&fmtexheader, sample, sizeof(WavFmtExHeader));
+					memcpy(&sampleheader, sample, sizeof(WavSampleHeader));
+					//loop = sampleheader.loops;
 					sample += chunkheader.size;
 				}
-			}
-			else if (!memcmp(chunkheader.id, "data", 4))
-			{
-				if (fmtheader.format == 0x0001)
-				{
-					waveslot->SetNumberOfSamples(chunkheader.size);
+				else
 					sample += chunkheader.size;
-				}
-				else if (fmtheader.format == 0x0011)
-				{
-					//IMA ADPCM
-				}
-				else if (fmtheader.format == 0x0055)
-				{
-					//MP3 WAVE
-				}
+
+				sample += chunkheader.size & 1;
+				fileheader.size -= (((chunkheader.size + 1) & ~1) + 8);
 			}
-			else if (!memcmp(chunkheader.id, "smpl", 4))
-			{
-				memcpy(&sampleheader, sample, sizeof(WavSampleHeader));
-				//loop = sampleheader.loops;
-				sample += chunkheader.size;
-			}
-			else
-				sample += chunkheader.size;
-
-			sample += chunkheader.size & 1;
-			fileheader.size -= (((chunkheader.size + 1) & ~1) + 8);
 		}
 	}
 }





More information about the Bf-blender-cvs mailing list