Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/intern
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2008-10-12 04:51:55 +0400
committerCampbell Barton <ideasman42@gmail.com>2008-10-12 04:51:55 +0400
commit0d71c0a9af160963ddadde4a220c08c88011c25f (patch)
treeaed450695173a21b6c983ca1f769a67c7f27522e /intern
parentd241d0a37993ef9fd92cbc53f51fa35e0963d837 (diff)
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.
Diffstat (limited to 'intern')
-rw-r--r--intern/SoundSystem/SND_Utils.h4
-rw-r--r--intern/SoundSystem/fmod/SND_FmodDevice.cpp2
-rw-r--r--intern/SoundSystem/intern/SND_Utils.cpp112
3 files changed, 60 insertions, 58 deletions
diff --git a/intern/SoundSystem/SND_Utils.h b/intern/SoundSystem/SND_Utils.h
index c54aa434eec..26cf1bda11c 100644
--- a/intern/SoundSystem/SND_Utils.h
+++ b/intern/SoundSystem/SND_Utils.h
@@ -97,8 +97,8 @@ extern unsigned int SND_GetSampleFormat(void* sample);
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);
diff --git a/intern/SoundSystem/fmod/SND_FmodDevice.cpp b/intern/SoundSystem/fmod/SND_FmodDevice.cpp
index cc252954fea..3ba0802a5b0 100644
--- a/intern/SoundSystem/fmod/SND_FmodDevice.cpp
+++ b/intern/SoundSystem/fmod/SND_FmodDevice.cpp
@@ -162,7 +162,7 @@ SND_WaveSlot* SND_FmodDevice::LoadSample(const STR_String& name,
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);
diff --git a/intern/SoundSystem/intern/SND_Utils.cpp b/intern/SoundSystem/intern/SND_Utils.cpp
index 754c8b029a1..58023dd5c50 100644
--- a/intern/SoundSystem/intern/SND_Utils.cpp
+++ b/intern/SoundSystem/intern/SND_Utils.cpp
@@ -285,10 +285,9 @@ unsigned int SND_GetBitRate(void* sample)
/* 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 @@ unsigned int SND_GetNumberOfSamples(void* sample)
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 @@ unsigned int SND_GetNumberOfSamples(void* sample)
/* 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 @@ unsigned int SND_GetHeaderSize(void* sample)
/* 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 @@ void SND_GetSampleInfo(signed char* sample, SND_WaveSlot* waveslot)
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))
- {
- memcpy(&fmtheader, sample, sizeof(WavFmtHeader));
- waveslot->SetSampleFormat(fmtheader.format);
-
- 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))
+ while ((fileheader.size > 0) && (memcpy(&chunkheader, sample, sizeof(WavChunkHeader))))
{
- if (fmtheader.format == 0x0001)
+ sample += sizeof(WavChunkHeader);
+ if (!memcmp(chunkheader.id, "fmt ", 4))
{
- waveslot->SetNumberOfSamples(chunkheader.size);
- sample += chunkheader.size;
+ memcpy(&fmtheader, sample, sizeof(WavFmtHeader));
+ waveslot->SetSampleFormat(fmtheader.format);
+
+ 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 (fmtheader.format == 0x0011)
+ else if (!memcmp(chunkheader.id, "data", 4))
{
- //IMA ADPCM
+ 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 (fmtheader.format == 0x0055)
+ else if (!memcmp(chunkheader.id, "smpl", 4))
{
- //MP3 WAVE
+ memcpy(&sampleheader, sample, sizeof(WavSampleHeader));
+ //loop = sampleheader.loops;
+ sample += chunkheader.size;
}
- }
- else if (!memcmp(chunkheader.id, "smpl", 4))
- {
- memcpy(&sampleheader, sample, sizeof(WavSampleHeader));
- //loop = sampleheader.loops;
- sample += chunkheader.size;
- }
- else
- sample += chunkheader.size;
+ else
+ sample += chunkheader.size;
- sample += chunkheader.size & 1;
- fileheader.size -= (((chunkheader.size + 1) & ~1) + 8);
+ sample += chunkheader.size & 1;
+ fileheader.size -= (((chunkheader.size + 1) & ~1) + 8);
+ }
}
}
}