diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2012-03-01 17:26:03 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2012-03-05 01:37:56 +0100 |
commit | ccb76ad91f2b97009b06c22ae1b2e0234dbf26ca (patch) | |
tree | 5155f645545c95cf7ab4af3a56fb30d434173451 /libavcodec | |
parent | 2af8f2cea6c94eba3a15820194cb7374b366976a (diff) | |
download | ffmpeg-ccb76ad91f2b97009b06c22ae1b2e0234dbf26ca.tar.gz |
cook: check decouple values.
This fixes a out of global array read in the cplscale* tables.
Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec')
-rw-r--r-- | libavcodec/cook.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/libavcodec/cook.c b/libavcodec/cook.c index 294044e7f2..36f02ac7ea 100644 --- a/libavcodec/cook.c +++ b/libavcodec/cook.c @@ -761,7 +761,7 @@ static void imlt_gain(COOKContext *q, float *inbuffer, * @param decouple_tab decoupling array * */ -static void decouple_info(COOKContext *q, COOKSubpacket *p, int *decouple_tab) +static int decouple_info(COOKContext *q, COOKSubpacket *p, int *decouple_tab) { int i; int vlc = get_bits1(&q->gb); @@ -776,8 +776,15 @@ static void decouple_info(COOKContext *q, COOKSubpacket *p, int *decouple_tab) for (i = 0; i < length; i++) decouple_tab[start + i] = get_vlc2(&q->gb, p->ccpl.table, p->ccpl.bits, 2); else - for (i = 0; i < length; i++) - decouple_tab[start + i] = get_bits(&q->gb, p->js_vlc_bits); + for (i = 0; i < length; i++) { + int v = get_bits(&q->gb, p->js_vlc_bits); + if (v == (1<<p->js_vlc_bits)-1) { + av_log(q->avctx, AV_LOG_ERROR, "decouple value too large\n"); + return AVERROR_INVALIDDATA; + } + decouple_tab[start + i] = v; + } + return 0; } /* @@ -829,7 +836,8 @@ static int joint_decode(COOKContext *q, COOKSubpacket *p, float *mlt_buffer1, /* Make sure the buffers are zeroed out. */ memset(mlt_buffer1, 0, 1024 * sizeof(*mlt_buffer1)); memset(mlt_buffer2, 0, 1024 * sizeof(*mlt_buffer2)); - decouple_info(q, p, decouple_tab); + if ((ret = decouple_info(q, p, decouple_tab)) < 0) + return ret; if ((ret = mono_decode(q, p, decode_buffer)) < 0) return ret; /* The two channels are stored interleaved in decode_buffer. */ |