avcodec/mjpegdec: check bits per pixel for changes similar to dimensions

Fixes out of array accesses
Fixes: asan_heap-oob_16668e9_2_asan_heap-oob_16668e9_346_miss_congeniality_pegasus_mjpg.avi

Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 5c378d6a6d)

Conflicts:

	libavcodec/mjpegdec.c
(cherry picked from commit 94371a404c663c3dae3d542fa43951567ab67f82)

Conflicts:

	libavcodec/mjpegdec.c
This commit is contained in:
Michael Niedermayer
2014-10-03 01:50:27 +02:00
parent d44d87e172
commit 29abba3572

View File

@@ -211,7 +211,7 @@ int ff_mjpeg_decode_dht(MJpegDecodeContext *s)
int ff_mjpeg_decode_sof(MJpegDecodeContext *s) int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
{ {
int len, nb_components, i, width, height, pix_fmt_id; int len, nb_components, i, width, height, bits, pix_fmt_id;
int h_count[MAX_COMPONENTS]; int h_count[MAX_COMPONENTS];
int v_count[MAX_COMPONENTS]; int v_count[MAX_COMPONENTS];
@@ -220,14 +220,14 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
/* XXX: verify len field validity */ /* XXX: verify len field validity */
len = get_bits(&s->gb, 16); len = get_bits(&s->gb, 16);
s->bits = get_bits(&s->gb, 8); bits = get_bits(&s->gb, 8);
if (s->pegasus_rct) if (s->pegasus_rct)
s->bits = 9; bits = 9;
if (s->bits == 9 && !s->pegasus_rct) if (bits == 9 && !s->pegasus_rct)
s->rct = 1; // FIXME ugly s->rct = 1; // FIXME ugly
if (s->bits != 8 && !s->lossless) { if (bits != 8 && !s->lossless) {
av_log(s->avctx, AV_LOG_ERROR, "only 8 bits/component accepted\n"); av_log(s->avctx, AV_LOG_ERROR, "only 8 bits/component accepted\n");
return -1; return -1;
} }
@@ -259,7 +259,7 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
} }
if (s->ls && !(s->bits <= 8 || nb_components == 1)) { if (s->ls && !(bits <= 8 || nb_components == 1)) {
av_log_missing_feature(s->avctx, av_log_missing_feature(s->avctx,
"For JPEG-LS anything except <= 8 bits/component" "For JPEG-LS anything except <= 8 bits/component"
" or 16-bit gray", 0); " or 16-bit gray", 0);
@@ -307,12 +307,14 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
/* if different size, realloc/alloc picture */ /* if different size, realloc/alloc picture */
if ( width != s->width || height != s->height if ( width != s->width || height != s->height
|| bits != s->bits
|| memcmp(s->h_count, h_count, sizeof(h_count[0])*nb_components) || memcmp(s->h_count, h_count, sizeof(h_count[0])*nb_components)
|| memcmp(s->v_count, v_count, sizeof(v_count[0])*nb_components)) { || memcmp(s->v_count, v_count, sizeof(v_count[0])*nb_components)) {
av_freep(&s->qscale_table); av_freep(&s->qscale_table);
s->width = width; s->width = width;
s->height = height; s->height = height;
s->bits = bits;
memcpy(s->h_count, h_count, sizeof(h_count)); memcpy(s->h_count, h_count, sizeof(h_count));
memcpy(s->v_count, v_count, sizeof(v_count)); memcpy(s->v_count, v_count, sizeof(v_count));
s->interlaced = 0; s->interlaced = 0;