diff options
Diffstat (limited to '')
-rw-r--r-- | linden/indra/llaudio/llaudiodecodemgr.cpp | 62 |
1 files changed, 46 insertions, 16 deletions
diff --git a/linden/indra/llaudio/llaudiodecodemgr.cpp b/linden/indra/llaudio/llaudiodecodemgr.cpp index afb3c33..a14d4ec 100644 --- a/linden/indra/llaudio/llaudiodecodemgr.cpp +++ b/linden/indra/llaudio/llaudiodecodemgr.cpp | |||
@@ -33,18 +33,18 @@ | |||
33 | 33 | ||
34 | #include "llaudiodecodemgr.h" | 34 | #include "llaudiodecodemgr.h" |
35 | 35 | ||
36 | #include "vorbisdecode.h" | 36 | #include "llvorbisdecode.h" |
37 | #include "audioengine.h" | 37 | #include "llaudioengine.h" |
38 | #include "lllfsthread.h" | 38 | #include "lllfsthread.h" |
39 | #include "llvfile.h" | 39 | #include "llvfile.h" |
40 | #include "llstring.h" | 40 | #include "llstring.h" |
41 | #include "lldir.h" | 41 | #include "lldir.h" |
42 | #include "llendianswizzle.h" | 42 | #include "llendianswizzle.h" |
43 | #include "audioengine.h" | ||
44 | #include "llassetstorage.h" | 43 | #include "llassetstorage.h" |
45 | 44 | ||
46 | #include "vorbis/codec.h" | 45 | #include "vorbis/codec.h" |
47 | #include "vorbis/vorbisfile.h" | 46 | #include "vorbis/vorbisfile.h" |
47 | #include "llvorbisencode.h" | ||
48 | 48 | ||
49 | extern LLAudioEngine *gAudiop; | 49 | extern LLAudioEngine *gAudiop; |
50 | 50 | ||
@@ -218,11 +218,42 @@ BOOL LLVorbisDecodeState::initDecode() | |||
218 | return(FALSE); | 218 | return(FALSE); |
219 | } | 219 | } |
220 | 220 | ||
221 | size_t size_guess = (size_t)ov_pcm_total(&mVF, -1); | 221 | S32 sample_count = ov_pcm_total(&mVF, -1); |
222 | size_t size_guess = (size_t)sample_count; | ||
222 | vorbis_info* vi = ov_info(&mVF, -1); | 223 | vorbis_info* vi = ov_info(&mVF, -1); |
223 | size_guess *= vi->channels; | 224 | size_guess *= vi->channels; |
224 | size_guess *= 2; | 225 | size_guess *= 2; |
225 | size_guess += 2048; | 226 | size_guess += 2048; |
227 | |||
228 | bool abort_decode = false; | ||
229 | |||
230 | if( vi->channels < 1 || vi->channels > LLVORBIS_CLIP_MAX_CHANNELS ) | ||
231 | { | ||
232 | abort_decode = true; | ||
233 | llwarns << "Bad channel count: " << vi->channels << llendl; | ||
234 | } | ||
235 | |||
236 | if( (size_t)sample_count > LLVORBIS_CLIP_REJECT_SAMPLES ) | ||
237 | { | ||
238 | abort_decode = true; | ||
239 | llwarns << "Illegal sample count: " << sample_count << llendl; | ||
240 | } | ||
241 | |||
242 | if( size_guess > LLVORBIS_CLIP_REJECT_SIZE ) | ||
243 | { | ||
244 | abort_decode = true; | ||
245 | llwarns << "Illegal sample size: " << size_guess << llendl; | ||
246 | } | ||
247 | |||
248 | if( abort_decode ) | ||
249 | { | ||
250 | llwarns << "Canceling initDecode. Bad asset: " << mUUID << llendl; | ||
251 | llwarns << "Bad asset encoded by: " << ov_comment(&mVF,-1)->vendor << llendl; | ||
252 | delete mInFilep; | ||
253 | mInFilep = NULL; | ||
254 | return FALSE; | ||
255 | } | ||
256 | |||
226 | mWAVBuffer.reserve(size_guess); | 257 | mWAVBuffer.reserve(size_guess); |
227 | mWAVBuffer.resize(WAV_HEADER_SIZE); | 258 | mWAVBuffer.resize(WAV_HEADER_SIZE); |
228 | 259 | ||
@@ -375,16 +406,16 @@ BOOL LLVorbisDecodeState::finishDecode() | |||
375 | 406 | ||
376 | // write "data" chunk length, in little-endian format | 407 | // write "data" chunk length, in little-endian format |
377 | S32 data_length = mWAVBuffer.size() - WAV_HEADER_SIZE; | 408 | S32 data_length = mWAVBuffer.size() - WAV_HEADER_SIZE; |
378 | mWAVBuffer[40] = (data_length - 8) & 0x000000FF; | 409 | mWAVBuffer[40] = (data_length) & 0x000000FF; |
379 | mWAVBuffer[41] = ((data_length - 8)>> 8) & 0x000000FF; | 410 | mWAVBuffer[41] = (data_length >> 8) & 0x000000FF; |
380 | mWAVBuffer[42] = ((data_length - 8)>> 16) & 0x000000FF; | 411 | mWAVBuffer[42] = (data_length >> 16) & 0x000000FF; |
381 | mWAVBuffer[43] = ((data_length - 8)>> 24) & 0x000000FF; | 412 | mWAVBuffer[43] = (data_length >> 24) & 0x000000FF; |
382 | |||
383 | // write overall "RIFF" length, in little-endian format | 413 | // write overall "RIFF" length, in little-endian format |
384 | mWAVBuffer[4] = (data_length + 28) & 0x000000FF; | 414 | data_length += 36; |
385 | mWAVBuffer[5] = ((data_length + 28) >> 8) & 0x000000FF; | 415 | mWAVBuffer[4] = (data_length) & 0x000000FF; |
386 | mWAVBuffer[6] = ((data_length + 28) >> 16) & 0x000000FF; | 416 | mWAVBuffer[5] = (data_length >> 8) & 0x000000FF; |
387 | mWAVBuffer[7] = ((data_length + 28) >> 24) & 0x000000FF; | 417 | mWAVBuffer[6] = (data_length >> 16) & 0x000000FF; |
418 | mWAVBuffer[7] = (data_length >> 24) & 0x000000FF; | ||
388 | 419 | ||
389 | // | 420 | // |
390 | // FUDGECAKES!!! Vorbis encode/decode messes up loop point transitions (pop) | 421 | // FUDGECAKES!!! Vorbis encode/decode messes up loop point transitions (pop) |
@@ -396,8 +427,7 @@ BOOL LLVorbisDecodeState::finishDecode() | |||
396 | S32 fade_length; | 427 | S32 fade_length; |
397 | char pcmout[4096]; /*Flawfinder: ignore*/ | 428 | char pcmout[4096]; /*Flawfinder: ignore*/ |
398 | 429 | ||
399 | fade_length = llmin((S32)128,(S32)(data_length)/8); | 430 | fade_length = llmin((S32)128,(S32)(data_length-36)/8); |
400 | |||
401 | if((S32)mWAVBuffer.size() >= (WAV_HEADER_SIZE + 2* fade_length)) | 431 | if((S32)mWAVBuffer.size() >= (WAV_HEADER_SIZE + 2* fade_length)) |
402 | { | 432 | { |
403 | memcpy(pcmout, &mWAVBuffer[WAV_HEADER_SIZE], (2 * fade_length)); /*Flawfinder: ignore*/ | 433 | memcpy(pcmout, &mWAVBuffer[WAV_HEADER_SIZE], (2 * fade_length)); /*Flawfinder: ignore*/ |
@@ -437,7 +467,7 @@ BOOL LLVorbisDecodeState::finishDecode() | |||
437 | } | 467 | } |
438 | } | 468 | } |
439 | 469 | ||
440 | if (0 == data_length) | 470 | if (36 == data_length) |
441 | { | 471 | { |
442 | llwarns << "BAD Vorbis decode in finishDecode!" << llendl; | 472 | llwarns << "BAD Vorbis decode in finishDecode!" << llendl; |
443 | mValid = FALSE; | 473 | mValid = FALSE; |