audio: Make sure audio stream resampling doesn't overflow buffers.
authorRyan C. Gordon <icculus@icculus.org>
Wed, 11 Oct 2017 02:03:05 -0400
changeset 11591c79a9f64ddb2
parent 11590 ca6aa7f5488d
child 11592 61260a51fc60
audio: Make sure audio stream resampling doesn't overflow buffers.
src/audio/SDL_audiocvt.c
     1.1 --- a/src/audio/SDL_audiocvt.c	Wed Oct 11 01:37:11 2017 -0400
     1.2 +++ b/src/audio/SDL_audiocvt.c	Wed Oct 11 02:03:05 2017 -0400
     1.3 @@ -1224,6 +1224,7 @@
     1.4      const int paddingbytes = paddingsamples * sizeof (float);
     1.5      float *lpadding = (float *) stream->resampler_state;
     1.6      const float *rpadding = (const float *) inbufend; /* we set this up so there are valid padding samples at the end of the input buffer. */
     1.7 +    const int cpy = SDL_min(inbuflen, paddingbytes);
     1.8      int retval;
     1.9  
    1.10      SDL_assert(inbuf != ((const float *) outbuf));  /* SDL_AudioStreamPut() shouldn't allow in-place resamples. */
    1.11 @@ -1231,7 +1232,7 @@
    1.12      retval = SDL_ResampleAudio(chans, inrate, outrate, lpadding, rpadding, inbuf, inbuflen, outbuf, outbuflen);
    1.13  
    1.14      /* update our left padding with end of current input, for next run. */
    1.15 -    SDL_memcpy(lpadding, inbufend - paddingbytes, paddingbytes);
    1.16 +    SDL_memcpy((lpadding + paddingsamples) - (cpy / sizeof (float)), inbufend - cpy, cpy);
    1.17      return retval;
    1.18  }
    1.19  
    1.20 @@ -1462,14 +1463,19 @@
    1.21          SDL_memcpy(stream->resampler_padding, workbuf + (buflen - neededpaddingbytes), neededpaddingbytes);
    1.22  
    1.23          resamplebuf = workbuf + buflen;  /* skip to second piece of workbuf. */
    1.24 -        buflen = stream->resampler_func(stream, workbuf, buflen - neededpaddingbytes, resamplebuf, resamplebuflen);
    1.25 +        SDL_assert(buflen >= neededpaddingbytes);
    1.26 +        if (buflen > neededpaddingbytes) {
    1.27 +            buflen = stream->resampler_func(stream, workbuf, buflen - neededpaddingbytes, resamplebuf, resamplebuflen);
    1.28 +        } else {
    1.29 +            buflen = 0;
    1.30 +        }
    1.31  
    1.32          #if DEBUG_AUDIOSTREAM
    1.33          printf("AUDIOSTREAM: After resampling we have %d bytes\n", buflen);
    1.34          #endif
    1.35      }
    1.36  
    1.37 -    if (stream->cvt_after_resampling.needed) {
    1.38 +    if (stream->cvt_after_resampling.needed && (buflen > 0)) {
    1.39          stream->cvt_after_resampling.buf = resamplebuf;
    1.40          stream->cvt_after_resampling.len = buflen;
    1.41          if (SDL_ConvertAudio(&stream->cvt_after_resampling) == -1) {
    1.42 @@ -1487,7 +1493,7 @@
    1.43      #endif
    1.44  
    1.45      /* resamplebuf holds the final output, even if we didn't resample. */
    1.46 -    return SDL_WriteToDataQueue(stream->queue, resamplebuf, buflen);
    1.47 +    return buflen ? SDL_WriteToDataQueue(stream->queue, resamplebuf, buflen) : 0;
    1.48  }
    1.49  
    1.50  void