summaryrefslogtreecommitdiff
path: root/libavcodec/mjpegdec.c
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2012-11-30 03:58:38 +0100
committerMichael Niedermayer <michaelni@gmx.at>2012-11-30 04:17:03 +0100
commita2f680c7bc7642c687aeb4e14d00ac74833c7a09 (patch)
tree23fc4da302b8765864cebc13496f687150411414 /libavcodec/mjpegdec.c
parent08d0969c1402ccec4dce44bd430128fb59d7b790 (diff)
mjpegdec: check h/v_count, fix context becoming inconsistent and causing out of array accesses.
This also fixes a long standing comment in the code. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec/mjpegdec.c')
-rw-r--r--libavcodec/mjpegdec.c30
1 files changed, 18 insertions, 12 deletions
diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c
index 8b4d5f7474..04debbf8b5 100644
--- a/libavcodec/mjpegdec.c
+++ b/libavcodec/mjpegdec.c
@@ -211,6 +211,8 @@ int ff_mjpeg_decode_dht(MJpegDecodeContext *s)
int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
{
int len, nb_components, i, width, height, pix_fmt_id;
+ int h_count[MAX_COMPONENTS];
+ int v_count[MAX_COMPONENTS];
s->cur_scan = 0;
s->upscale_h = s->upscale_v = 0;
@@ -264,19 +266,19 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
s->nb_components = nb_components;
s->h_max = 1;
s->v_max = 1;
- memset(s->h_count, 0, sizeof(s->h_count));
- memset(s->v_count, 0, sizeof(s->v_count));
+ memset(h_count, 0, sizeof(h_count));
+ memset(v_count, 0, sizeof(v_count));
for (i = 0; i < nb_components; i++) {
/* component id */
s->component_id[i] = get_bits(&s->gb, 8) - 1;
- s->h_count[i] = get_bits(&s->gb, 4);
- s->v_count[i] = get_bits(&s->gb, 4);
+ h_count[i] = get_bits(&s->gb, 4);
+ v_count[i] = get_bits(&s->gb, 4);
/* compute hmax and vmax (only used in interleaved case) */
- if (s->h_count[i] > s->h_max)
- s->h_max = s->h_count[i];
- if (s->v_count[i] > s->v_max)
- s->v_max = s->v_count[i];
- if (!s->h_count[i] || !s->v_count[i]) {
+ if (h_count[i] > s->h_max)
+ s->h_max = h_count[i];
+ if (v_count[i] > s->v_max)
+ s->v_max = v_count[i];
+ if (!h_count[i] || !v_count[i]) {
av_log(s->avctx, AV_LOG_ERROR, "h/v_count is 0\n");
return -1;
}
@@ -284,7 +286,7 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
if (s->quant_index[i] >= 4)
return AVERROR_INVALIDDATA;
av_log(s->avctx, AV_LOG_DEBUG, "component %d %d:%d id: %d quant:%d\n",
- i, s->h_count[i], s->v_count[i],
+ i, h_count[i], v_count[i],
s->component_id[i], s->quant_index[i]);
}
@@ -297,13 +299,17 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
s->rgb = 1;
/* if different size, realloc/alloc picture */
- /* XXX: also check h_count and v_count */
- if (width != s->width || height != s->height) {
+ if ( width != s->width || height != s->height
+ || memcmp(s->h_count, h_count, sizeof(h_count[0])*nb_components)
+ || memcmp(s->v_count, v_count, sizeof(v_count[0])*nb_components)) {
av_freep(&s->qscale_table);
s->width = width;
s->height = height;
+ memcpy(s->h_count, h_count, sizeof(h_count));
+ memcpy(s->v_count, v_count, sizeof(v_count));
s->interlaced = 0;
+ s->got_picture = 0;
/* test interlaced mode */
if (s->first_picture &&