From 9938e450c8575e0a4640dcbefb87d26d6bab9e4d Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Fri, 24 Jan 2014 16:22:44 +0100 Subject: [PATCH 1/3] mpeg12: check scantable indices in all decode_block functions Add checks to the fast functions used with CODEC_FLAGS2_FAST and move the check for all other functions to before the invalid memory is accessed. Fixes https://trac.videolan.org/vlc/ticket/9713 with CODEC_FLAGS2_FAST. CC: libav-stable@libav.org --- libavcodec/mpeg12.c | 48 +++++++++++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c index 436b4cf376..4db2753b40 100644 --- a/libavcodec/mpeg12.c +++ b/libavcodec/mpeg12.c @@ -80,6 +80,15 @@ static int mpeg_decode_motion(MpegEncContext *s, int fcode, int pred) return sign_extend(val, 5 + shift); } +#define check_scantable_index(ctx, x) \ + do { \ + if ((x) > 63) { \ + av_log(ctx->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", \ + ctx->mb_x, ctx->mb_y); \ + return AVERROR_INVALIDDATA; \ + } \ + } while (0) \ + static inline int mpeg1_decode_block_intra(MpegEncContext *s, DCTELEM *block, int n) { int level, dc, diff, i, j, run; @@ -111,6 +120,7 @@ static inline int mpeg1_decode_block_intra(MpegEncContext *s, DCTELEM *block, in break; } else if (level != 0) { i += run; + check_scantable_index(s, i); j = scantable[i]; level = (level * qscale * quant_matrix[j]) >> 4; level = (level - 1) | 1; @@ -127,6 +137,7 @@ static inline int mpeg1_decode_block_intra(MpegEncContext *s, DCTELEM *block, in level = SHOW_UBITS(re, &s->gb, 8) ; LAST_SKIP_BITS(re, &s->gb, 8); } i += run; + check_scantable_index(s, i); j = scantable[i]; if (level < 0) { level = -level; @@ -138,10 +149,6 @@ static inline int mpeg1_decode_block_intra(MpegEncContext *s, DCTELEM *block, in level = (level - 1) | 1; } } - if (i > 63) { - av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y); - return -1; - } block[j] = level; } @@ -261,6 +268,7 @@ static inline int mpeg1_fast_decode_block_inter(MpegEncContext *s, DCTELEM *bloc if (level != 0) { i += run; + check_scantable_index(s, i); j = scantable[i]; level = ((level * 2 + 1) * qscale) >> 1; level = (level - 1) | 1; @@ -277,6 +285,7 @@ static inline int mpeg1_fast_decode_block_inter(MpegEncContext *s, DCTELEM *bloc level = SHOW_UBITS(re, &s->gb, 8) ; SKIP_BITS(re, &s->gb, 8); } i += run; + check_scantable_index(s, i); j = scantable[i]; if (level < 0) { level = -level; @@ -342,6 +351,7 @@ static inline int mpeg2_decode_block_non_intra(MpegEncContext *s, DCTELEM *block if (level != 0) { i += run; + check_scantable_index(s, i); j = scantable[i]; level = ((level * 2 + 1) * qscale * quant_matrix[j]) >> 5; level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); @@ -353,6 +363,7 @@ static inline int mpeg2_decode_block_non_intra(MpegEncContext *s, DCTELEM *block level = SHOW_SBITS(re, &s->gb, 12); SKIP_BITS(re, &s->gb, 12); i += run; + check_scantable_index(s, i); j = scantable[i]; if (level < 0) { level = ((-level * 2 + 1) * qscale * quant_matrix[j]) >> 5; @@ -361,10 +372,6 @@ static inline int mpeg2_decode_block_non_intra(MpegEncContext *s, DCTELEM *block level = ((level * 2 + 1) * qscale * quant_matrix[j]) >> 5; } } - if (i > 63) { - av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y); - return -1; - } mismatch ^= level; block[j] = level; @@ -411,6 +418,7 @@ static inline int mpeg2_fast_decode_block_non_intra(MpegEncContext *s, if (level != 0) { i += run; + check_scantable_index(s, i); j = scantable[i]; level = ((level * 2 + 1) * qscale) >> 1; level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); @@ -422,6 +430,7 @@ static inline int mpeg2_fast_decode_block_non_intra(MpegEncContext *s, level = SHOW_SBITS(re, &s->gb, 12); SKIP_BITS(re, &s->gb, 12); i += run; + check_scantable_index(s, i); j = scantable[i]; if (level < 0) { level = ((-level * 2 + 1) * qscale) >> 1; @@ -488,6 +497,7 @@ static inline int mpeg2_decode_block_intra(MpegEncContext *s, DCTELEM *block, in break; } else if (level != 0) { i += run; + check_scantable_index(s, i); j = scantable[i]; level = (level * qscale * quant_matrix[j]) >> 4; level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); @@ -498,6 +508,7 @@ static inline int mpeg2_decode_block_intra(MpegEncContext *s, DCTELEM *block, in UPDATE_CACHE(re, &s->gb); level = SHOW_SBITS(re, &s->gb, 12); SKIP_BITS(re, &s->gb, 12); i += run; + check_scantable_index(s, i); j = scantable[i]; if (level < 0) { level = (-level * qscale * quant_matrix[j]) >> 4; @@ -506,10 +517,6 @@ static inline int mpeg2_decode_block_intra(MpegEncContext *s, DCTELEM *block, in level = (level * qscale * quant_matrix[j]) >> 4; } } - if (i > 63) { - av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y); - return -1; - } mismatch ^= level; block[j] = level; @@ -524,10 +531,10 @@ static inline int mpeg2_decode_block_intra(MpegEncContext *s, DCTELEM *block, in static inline int mpeg2_fast_decode_block_intra(MpegEncContext *s, DCTELEM *block, int n) { - int level, dc, diff, j, run; + int level, dc, diff, i, j, run; int component; RLTable *rl; - uint8_t * scantable = s->intra_scantable.permutated; + uint8_t * const scantable = s->intra_scantable.permutated; const uint16_t *quant_matrix; const int qscale = s->qscale; @@ -546,6 +553,7 @@ static inline int mpeg2_fast_decode_block_intra(MpegEncContext *s, DCTELEM *bloc dc += diff; s->last_dc[component] = dc; block[0] = dc << (3 - s->intra_dc_precision); + i = 0; if (s->intra_vlc_format) rl = &ff_rl_mpeg2; else @@ -561,8 +569,9 @@ static inline int mpeg2_fast_decode_block_intra(MpegEncContext *s, DCTELEM *bloc if (level == 127) { break; } else if (level != 0) { - scantable += run; - j = *scantable; + i += run; + check_scantable_index(s, i); + j = scantable[i]; level = (level * qscale * quant_matrix[j]) >> 4; level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); LAST_SKIP_BITS(re, &s->gb, 1); @@ -571,8 +580,9 @@ static inline int mpeg2_fast_decode_block_intra(MpegEncContext *s, DCTELEM *bloc run = SHOW_UBITS(re, &s->gb, 6) + 1; LAST_SKIP_BITS(re, &s->gb, 6); UPDATE_CACHE(re, &s->gb); level = SHOW_SBITS(re, &s->gb, 12); SKIP_BITS(re, &s->gb, 12); - scantable += run; - j = *scantable; + i += run; + check_scantable_index(s, i); + j = scantable[i]; if (level < 0) { level = (-level * qscale * quant_matrix[j]) >> 4; level = -level; @@ -586,7 +596,7 @@ static inline int mpeg2_fast_decode_block_intra(MpegEncContext *s, DCTELEM *bloc CLOSE_READER(re, &s->gb); } - s->block_last_index[n] = scantable - s->intra_scantable.permutated; + s->block_last_index[n] = i; return 0; } From 1dce4a031f8dca167ce5f58da066e296d0231a4a Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Wed, 5 Mar 2014 10:41:33 +0100 Subject: [PATCH 2/3] avfilter: Add missing emms_c when needed Arch specific calls should have an emms_c following to keep the cpu state consistent. Reported-By: wm4 CC: libav-stable@libav.org --- libavfilter/vf_gradfun.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavfilter/vf_gradfun.c b/libavfilter/vf_gradfun.c index c6663c4102..525aec91a8 100644 --- a/libavfilter/vf_gradfun.c +++ b/libavfilter/vf_gradfun.c @@ -113,6 +113,7 @@ static void filter(GradFunContext *ctx, uint8_t *dst, uint8_t *src, int width, i ctx->filter_line(dst + y * dst_linesize, src + y * src_linesize, dc - r / 2, width, thresh, dither[y & 7]); if (++y >= height) break; } + emms_c(); } static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) From 330c18032464a4e1f3da907e54db2e69a6fbfcda Mon Sep 17 00:00:00 2001 From: John Stebbins Date: Mon, 3 Mar 2014 20:20:14 +0000 Subject: [PATCH 3/3] matroskaenc: allow override of "writing application" tag Signed-off-by: Tim Walker CC: libav-stable@libav.org (cherry picked from commit 0092c1dd8dac2d9e185b58503b447a0d3fb5230d) --- libavformat/matroskaenc.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index e93dd65dff..8666bafc42 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -766,7 +766,8 @@ static int mkv_write_tag(AVFormatContext *s, AVDictionary *m, unsigned int eleme end_ebml_master(s->pb, targets); while ((t = av_dict_get(m, "", t, AV_DICT_IGNORE_SUFFIX))) - if (av_strcasecmp(t->key, "title")) + if (av_strcasecmp(t->key, "title") && + av_strcasecmp(t->key, "encoding_tool")) mkv_write_simpletag(s->pb, t); end_ebml_master(s->pb, tag); @@ -926,7 +927,10 @@ static int mkv_write_header(AVFormatContext *s) segment_uid[i] = av_lfg_get(&lfg); put_ebml_string(pb, MATROSKA_ID_MUXINGAPP , LIBAVFORMAT_IDENT); - put_ebml_string(pb, MATROSKA_ID_WRITINGAPP, LIBAVFORMAT_IDENT); + if ((tag = av_dict_get(s->metadata, "encoding_tool", NULL, 0))) + put_ebml_string(pb, MATROSKA_ID_WRITINGAPP, tag->value); + else + put_ebml_string(pb, MATROSKA_ID_WRITINGAPP, LIBAVFORMAT_IDENT); put_ebml_binary(pb, MATROSKA_ID_SEGMENTUID, segment_uid, 16); }