diff options
author | Linus Nielsen Feltzing <linus@haxx.se> | 2005-08-10 23:17:55 +0000 |
---|---|---|
committer | Linus Nielsen Feltzing <linus@haxx.se> | 2005-08-10 23:17:55 +0000 |
commit | 591d2890f11e5e9a2e762496486982ad222e25cb (patch) | |
tree | 78f3320f266f141898f07ecbbd81f0058ecf036a /apps | |
parent | 064c7afb6363f681b4082998beb5ee36a6fff22a (diff) | |
download | rockbox-591d2890f11e5e9a2e762496486982ad222e25cb.tar.gz rockbox-591d2890f11e5e9a2e762496486982ad222e25cb.zip |
patch #1255805 by Frederic Devernay - fix to buffer overflow in dsp.c
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7301 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
-rw-r--r-- | apps/dsp.c | 48 | ||||
-rw-r--r-- | apps/playback.c | 14 |
2 files changed, 44 insertions, 18 deletions
diff --git a/apps/dsp.c b/apps/dsp.c index 2a8a48e3a0..21effc5da3 100644 --- a/apps/dsp.c +++ b/apps/dsp.c | |||
@@ -474,13 +474,9 @@ long dsp_process(char* dst, char* src[], long size) | |||
474 | * the number of samples generated depends on the current state of the | 474 | * the number of samples generated depends on the current state of the |
475 | * resampler). | 475 | * resampler). |
476 | */ | 476 | */ |
477 | /* dsp_input_size MUST be called afterwards */ | ||
477 | long dsp_output_size(long size) | 478 | long dsp_output_size(long size) |
478 | { | 479 | { |
479 | if (dsp.stereo_mode == STEREO_MONO) | ||
480 | { | ||
481 | size *= 2; | ||
482 | } | ||
483 | |||
484 | if (dsp.sample_depth > NATIVE_DEPTH) | 480 | if (dsp.sample_depth > NATIVE_DEPTH) |
485 | { | 481 | { |
486 | size /= 2; | 482 | size /= 2; |
@@ -492,7 +488,22 @@ long dsp_output_size(long size) | |||
492 | + (dsp.frequency - 1)) / dsp.frequency); | 488 | + (dsp.frequency - 1)) / dsp.frequency); |
493 | } | 489 | } |
494 | 490 | ||
495 | return (size + 3) & ~3; | 491 | /* round to the next multiple of 2 (these are shorts) */ |
492 | size = (size + 1) & ~1; | ||
493 | |||
494 | if (dsp.stereo_mode == STEREO_MONO) | ||
495 | { | ||
496 | size *= 2; | ||
497 | } | ||
498 | |||
499 | /* now we have the size in bytes for two resampled channels, | ||
500 | * and the size in (short) must not exceed RESAMPLE_BUF_SIZE to | ||
501 | * avoid resample buffer overflow. One must call dsp_input_size() | ||
502 | * to get the correct input buffer size. */ | ||
503 | if (size > RESAMPLE_BUF_SIZE*2) | ||
504 | size = RESAMPLE_BUF_SIZE*2; | ||
505 | |||
506 | return size; | ||
496 | } | 507 | } |
497 | 508 | ||
498 | /* Given size bytes of output buffer, calculate number of bytes of input | 509 | /* Given size bytes of output buffer, calculate number of bytes of input |
@@ -500,22 +511,29 @@ long dsp_output_size(long size) | |||
500 | */ | 511 | */ |
501 | long dsp_input_size(long size) | 512 | long dsp_input_size(long size) |
502 | { | 513 | { |
514 | /* convert to number of output stereo samples. */ | ||
515 | size /= 2; | ||
516 | |||
517 | /* Mono means we need half input samples to fill the output buffer */ | ||
503 | if (dsp.stereo_mode == STEREO_MONO) | 518 | if (dsp.stereo_mode == STEREO_MONO) |
504 | { | ||
505 | size /= 2; | 519 | size /= 2; |
506 | } | ||
507 | |||
508 | if (dsp.sample_depth > NATIVE_DEPTH) | ||
509 | { | ||
510 | size *= 2; | ||
511 | } | ||
512 | 520 | ||
521 | /* size is now the number of resampled input samples. Convert to | ||
522 | original input samples. */ | ||
513 | if (dsp.frequency != NATIVE_FREQUENCY) | 523 | if (dsp.frequency != NATIVE_FREQUENCY) |
514 | { | 524 | { |
515 | size = (long) ((((unsigned long) size * dsp.frequency) | 525 | /* Use the real resampling delta = |
516 | + (NATIVE_FREQUENCY - 1)) / NATIVE_FREQUENCY); | 526 | * (unsigned long) dsp.frequency * 65536 / NATIVE_FREQUENCY, and |
527 | * round towards zero to avoid buffer overflows. */ | ||
528 | size = ((unsigned long)size * resample_data[0].delta) >> 16; | ||
517 | } | 529 | } |
518 | 530 | ||
531 | /* Convert back to bytes. */ | ||
532 | if (dsp.sample_depth > NATIVE_DEPTH) | ||
533 | size *= 4; | ||
534 | else | ||
535 | size *= 2; | ||
536 | |||
519 | return size; | 537 | return size; |
520 | } | 538 | } |
521 | 539 | ||
diff --git a/apps/playback.c b/apps/playback.c index 526fff376b..fb8232012e 100644 --- a/apps/playback.c +++ b/apps/playback.c | |||
@@ -196,12 +196,20 @@ bool codec_pcmbuf_insert_split_callback(void *ch1, void *ch2, | |||
196 | yield(); | 196 | yield(); |
197 | } | 197 | } |
198 | 198 | ||
199 | /* Get the real input_size for output_size bytes, guarding | ||
200 | * against resampling buffer overflows. */ | ||
199 | input_size = dsp_input_size(output_size); | 201 | input_size = dsp_input_size(output_size); |
200 | /* Guard against rounding errors (output_size can be too large). */ | 202 | if (input_size > length) { |
201 | input_size = MIN(input_size, length); | 203 | DEBUGF("Error: dsp_input_size(%ld=dsp_output_size(%ld))=%ld > %ld\n", |
202 | 204 | output_size, length, input_size, length); | |
205 | input_size = length; | ||
206 | } | ||
207 | |||
203 | if (input_size <= 0) { | 208 | if (input_size <= 0) { |
204 | pcmbuf_flush_buffer(0); | 209 | pcmbuf_flush_buffer(0); |
210 | DEBUGF("Warning: dsp_input_size(%ld=dsp_output_size(%ld))=%ld <= 0\n", | ||
211 | output_size, length, input_size); | ||
212 | /* should we really continue, or should we break? */ | ||
205 | continue; | 213 | continue; |
206 | } | 214 | } |
207 | 215 | ||