Fixed bug 1014 - SDL_ConvertAudio crashes

The patch Mark attached looks good and valgrind gives it a clean bill of health:

Mark.Howson@ntu.ac.uk 2010-12-15 07:45:25 PST

Reproducible here under Windows and Linux. Looking at the code for
SDL_Upsample_S16LSB_2c:

const int dstsize = (int) (((double)cvt->len_cvt) * cvt->rate_incr);
Sint16 *dst = ((Sint16 *) (cvt->buf + dstsize)) - 2;
const Sint16 *target = ((const Sint16 *) cvt->buf) - 2;
while (dst > target) {
   dst[1] = ((Sint16) SDL_SwapLE16(sample1));
   dst[0] = ((Sint16) SDL_SwapLE16(sample0));
   dst -= 2;
...

if dstsize is odd (and therefore dst), it'll write to target[1] which is one
byte before the allocated buf.

The attached patch to sdlgenaudiocvt.pl changes dst > target to dst >= target,
and removes the - $channels for the upsample case. The patch is not fully
tested, but seems to work here.
This commit is contained in:
Sam Lantinga 2012-01-08 17:10:57 -05:00
parent 6ebbe99d99
commit a9bcdb83a9
2 changed files with 304 additions and 304 deletions

File diff suppressed because it is too large Load diff

View file

@ -404,11 +404,11 @@ EOF
# Upsampling (growing the buffer) needs to work backwards, since we
# overwrite the buffer as we go.
if ($upsample) {
$endcomparison = '>'; # dst > target
$endcomparison = '>='; # dst > target
print <<EOF;
$fctype *dst = (($fctype *) (cvt->buf + dstsize)) - $channels;
const $fctype *src = (($fctype *) (cvt->buf + cvt->len_cvt)) - $channels;
const $fctype *target = ((const $fctype *) cvt->buf) - $channels;
const $fctype *target = ((const $fctype *) cvt->buf);
EOF
} else {
$endcomparison = '<'; # dst < target
@ -544,11 +544,11 @@ EOF
# Upsampling (growing the buffer) needs to work backwards, since we
# overwrite the buffer as we go.
if ($upsample) {
$endcomparison = '>'; # dst > target
$endcomparison = '>='; # dst > target
print <<EOF;
$fctype *dst = (($fctype *) (cvt->buf + dstsize)) - $channels;
const $fctype *src = (($fctype *) (cvt->buf + cvt->len_cvt)) - $channels;
const $fctype *target = ((const $fctype *) cvt->buf) - $channels;
const $fctype *target = ((const $fctype *) cvt->buf);
EOF
} else {
$endcomparison = '<'; # dst < target