summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorLinus Nielsen Feltzing <linus@haxx.se>2005-08-10 23:17:55 +0000
committerLinus Nielsen Feltzing <linus@haxx.se>2005-08-10 23:17:55 +0000
commit591d2890f11e5e9a2e762496486982ad222e25cb (patch)
tree78f3320f266f141898f07ecbbd81f0058ecf036a /apps
parent064c7afb6363f681b4082998beb5ee36a6fff22a (diff)
downloadrockbox-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.c48
-rw-r--r--apps/playback.c14
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 */
477long dsp_output_size(long size) 478long 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 */
501long dsp_input_size(long size) 512long 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