mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2026-06-16 04:32:47 +02:00
xa_adpcm: limit filter to prevent xa_adpcm_table[] array bounds overruns.
Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind
CC: libav-stable@libav.org
(cherry picked from commit 86020073db)
Signed-off-by: Reinhard Tartler <siretart@tauware.de>
This commit is contained in:
committed by
Reinhard Tartler
parent
c999a8ed65
commit
6e5c07f4c8
+20
-5
@@ -260,8 +260,9 @@ static inline short adpcm_yamaha_expand_nibble(ADPCMChannelStatus *c, unsigned c
|
||||
return c->predictor;
|
||||
}
|
||||
|
||||
static void xa_decode(short *out, const unsigned char *in,
|
||||
ADPCMChannelStatus *left, ADPCMChannelStatus *right, int inc)
|
||||
static int xa_decode(AVCodecContext *avctx,
|
||||
short *out, const unsigned char *in,
|
||||
ADPCMChannelStatus *left, ADPCMChannelStatus *right, int inc)
|
||||
{
|
||||
int i, j;
|
||||
int shift,filter,f0,f1;
|
||||
@@ -272,6 +273,12 @@ static void xa_decode(short *out, const unsigned char *in,
|
||||
|
||||
shift = 12 - (in[4+i*2] & 15);
|
||||
filter = in[4+i*2] >> 4;
|
||||
if (filter > 4) {
|
||||
av_log(avctx, AV_LOG_ERROR,
|
||||
"Invalid XA-ADPCM filter %d (max. allowed is 4)\n",
|
||||
filter);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
f0 = xa_adpcm_table[filter][0];
|
||||
f1 = xa_adpcm_table[filter][1];
|
||||
|
||||
@@ -299,7 +306,12 @@ static void xa_decode(short *out, const unsigned char *in,
|
||||
|
||||
shift = 12 - (in[5+i*2] & 15);
|
||||
filter = in[5+i*2] >> 4;
|
||||
|
||||
if (filter > 4) {
|
||||
av_log(avctx, AV_LOG_ERROR,
|
||||
"Invalid XA-ADPCM filter %d (max. allowed is 4)\n",
|
||||
filter);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
f0 = xa_adpcm_table[filter][0];
|
||||
f1 = xa_adpcm_table[filter][1];
|
||||
|
||||
@@ -323,6 +335,8 @@ static void xa_decode(short *out, const unsigned char *in,
|
||||
left->sample2 = s_2;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -782,8 +796,9 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data,
|
||||
break;
|
||||
case CODEC_ID_ADPCM_XA:
|
||||
while (buf_size >= 128) {
|
||||
xa_decode(samples, src, &c->status[0], &c->status[1],
|
||||
avctx->channels);
|
||||
if ((ret = xa_decode(avctx, samples, src, &c->status[0],
|
||||
&c->status[1], avctx->channels)) < 0)
|
||||
return ret;
|
||||
src += 128;
|
||||
samples += 28 * 8;
|
||||
buf_size -= 128;
|
||||
|
||||
Reference in New Issue
Block a user