From d0c4d61c8bfdc074d6c20fb57760ac6b3200d9a9 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Tue, 9 Apr 2013 15:25:20 +0200 Subject: [PATCH 1/4] qdm2: check that the FFT size is a power of 2 Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC:libav-stable@libav.org (cherry picked from commit 34f87a58532ed652a6e0283c1d044ee5df0aef0b) Signed-off-by: Reinhard Tartler --- libavcodec/qdm2.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libavcodec/qdm2.c b/libavcodec/qdm2.c index cfae824d95..17729d18c9 100644 --- a/libavcodec/qdm2.c +++ b/libavcodec/qdm2.c @@ -1838,6 +1838,10 @@ static av_cold int qdm2_decode_init(AVCodecContext *avctx) av_log(avctx, AV_LOG_ERROR, "Unknown FFT order (%d), contact the developers!\n", s->fft_order); return -1; } + if (s->fft_size != (1 << (s->fft_order - 1))) { + av_log(avctx, AV_LOG_ERROR, "FFT size %d not power of 2.\n", s->fft_size); + return AVERROR_INVALIDDATA; + } ff_rdft_init(&s->rdft_ctx, s->fft_order, IDFT_C2R); ff_mpadsp_init(&s->mpadsp); From 43039f9386d2d81eb39a9737b1c622bb83af36f8 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Mon, 8 Apr 2013 22:12:12 +0200 Subject: [PATCH 2/4] svq1dec: check that the reference frame has the same dimensions as the current one They can be different if the last keyframe failed to decode correctly. Fixes possible invalid reads in such a case. Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC:libav-stable@libav.org (cherry picked from commit b1bb8fb860b47e90dd67f0c5740698128fc82dcc) Signed-off-by: Reinhard Tartler --- libavcodec/svq1dec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavcodec/svq1dec.c b/libavcodec/svq1dec.c index 515604222b..19ff8d6594 100644 --- a/libavcodec/svq1dec.c +++ b/libavcodec/svq1dec.c @@ -692,7 +692,8 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data, } else { /* delta frame */ uint8_t *previous = s->prev->data[i]; - if (!previous) { + if (!previous || + s->prev->width != s->width || s->prev->height != s->height) { av_log(avctx, AV_LOG_ERROR, "Missing reference frame.\n"); result = AVERROR_INVALIDDATA; goto err; From a3410b5a1fcb4e965ceb40aa4d4a935df8a32f05 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Mon, 8 Apr 2013 22:15:54 +0200 Subject: [PATCH 3/4] svq1dec: clip motion vectors to the frame size. Fixes invalid reads for corrupted files. Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC:libav-stable@libav.org (cherry picked from commit ecff5acb5a738fcb4f9e206a12070dac4bf259b3) Signed-off-by: Reinhard Tartler --- libavcodec/svq1dec.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/libavcodec/svq1dec.c b/libavcodec/svq1dec.c index 19ff8d6594..82f9301e93 100644 --- a/libavcodec/svq1dec.c +++ b/libavcodec/svq1dec.c @@ -322,7 +322,8 @@ static void svq1_skip_block(uint8_t *current, uint8_t *previous, static int svq1_motion_inter_block(DSPContext *dsp, GetBitContext *bitbuf, uint8_t *current, uint8_t *previous, - int pitch, svq1_pmv *motion, int x, int y) + int pitch, svq1_pmv *motion, int x, int y, + int width, int height) { uint8_t *src; uint8_t *dst; @@ -352,10 +353,8 @@ static int svq1_motion_inter_block(DSPContext *dsp, GetBitContext *bitbuf, motion[x / 8 + 2].y = motion[x / 8 + 3].y = mv.y; - if (y + (mv.y >> 1) < 0) - mv.y = 0; - if (x + (mv.x >> 1) < 0) - mv.x = 0; + mv.x = av_clip(mv.x, -2 * x, 2 * (width - x - 16)); + mv.y = av_clip(mv.y, -2 * y, 2 * (height - y - 16)); src = &previous[(x + (mv.x >> 1)) + (y + (mv.y >> 1)) * pitch]; dst = current; @@ -367,7 +366,8 @@ static int svq1_motion_inter_block(DSPContext *dsp, GetBitContext *bitbuf, static int svq1_motion_inter_4v_block(DSPContext *dsp, GetBitContext *bitbuf, uint8_t *current, uint8_t *previous, - int pitch, svq1_pmv *motion, int x, int y) + int pitch, svq1_pmv *motion, int x, int y, + int width, int height) { uint8_t *src; uint8_t *dst; @@ -427,10 +427,8 @@ static int svq1_motion_inter_4v_block(DSPContext *dsp, GetBitContext *bitbuf, int mvy = pmv[i]->y + (i >> 1) * 16; // FIXME: clipping or padding? - if (y + (mvy >> 1) < 0) - mvy = 0; - if (x + (mvx >> 1) < 0) - mvx = 0; + mvx = av_clip(mvx, -2 * x, 2 * (width - x - 8)); + mvy = av_clip(mvy, -2 * y, 2 * (height - y - 8)); src = &previous[(x + (mvx >> 1)) + (y + (mvy >> 1)) * pitch]; dst = current; @@ -450,7 +448,8 @@ static int svq1_motion_inter_4v_block(DSPContext *dsp, GetBitContext *bitbuf, static int svq1_decode_delta_block(AVCodecContext *avctx, DSPContext *dsp, GetBitContext *bitbuf, uint8_t *current, uint8_t *previous, - int pitch, svq1_pmv *motion, int x, int y) + int pitch, svq1_pmv *motion, int x, int y, + int width, int height) { uint32_t block_type; int result = 0; @@ -475,7 +474,7 @@ static int svq1_decode_delta_block(AVCodecContext *avctx, DSPContext *dsp, case SVQ1_BLOCK_INTER: result = svq1_motion_inter_block(dsp, bitbuf, current, previous, - pitch, motion, x, y); + pitch, motion, x, y, width, height); if (result != 0) { av_dlog(avctx, "Error in svq1_motion_inter_block %i\n", result); @@ -486,7 +485,7 @@ static int svq1_decode_delta_block(AVCodecContext *avctx, DSPContext *dsp, case SVQ1_BLOCK_INTER_4V: result = svq1_motion_inter_4v_block(dsp, bitbuf, current, previous, - pitch, motion, x, y); + pitch, motion, x, y, width, height); if (result != 0) { av_dlog(avctx, "Error in svq1_motion_inter_4v_block %i\n", result); @@ -706,7 +705,7 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data, result = svq1_decode_delta_block(avctx, &s->dsp, &s->gb, ¤t[x], previous, linesize, - pmv, x, y); + pmv, x, y, width, height); if (result != 0) { av_dlog(avctx, "Error in svq1_decode_delta_block %i\n", From c8462bd17f35f435192281a2ea4ce8008a7398d3 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Thu, 20 Sep 2012 22:00:52 +0200 Subject: [PATCH 4/4] mp3dec: fallback to generic seeking when a TOC is not present Fixes seeking without a Xing/Info header. CC: libav-stable@libav.org Signed-off-by: Anton Khirnov (cherry picked from commit 505642f18276aed03278ac91b1f334ea888eac6a) Signed-off-by: Reinhard Tartler --- libavformat/mp3dec.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/libavformat/mp3dec.c b/libavformat/mp3dec.c index 48deefd126..9da9aa8b16 100644 --- a/libavformat/mp3dec.c +++ b/libavformat/mp3dec.c @@ -35,6 +35,10 @@ #define XING_TOC_COUNT 100 +typedef struct MP3DecContext { + int xing_toc; +} MP3DecContext; + /* mp3 read */ static int mp3_read_probe(AVProbeData *p) @@ -100,6 +104,7 @@ static int mp3_read_probe(AVProbeData *p) static void read_xing_toc(AVFormatContext *s, int64_t filesize, int64_t duration) { int i; + MP3DecContext *mp3 = s->priv_data; if (!filesize && !(filesize = avio_size(s->pb))) { @@ -115,6 +120,7 @@ static void read_xing_toc(AVFormatContext *s, int64_t filesize, int64_t duration av_rescale(i, duration, XING_TOC_COUNT), 0, 0, AVINDEX_KEYFRAME); } + mp3->xing_toc = 1; } /** @@ -238,11 +244,15 @@ static int mp3_read_packet(AVFormatContext *s, AVPacket *pkt) static int mp3_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) { + MP3DecContext *mp3 = s->priv_data; AVIndexEntry *ie; AVStream *st = s->streams[0]; int64_t ret = av_index_search_timestamp(st, timestamp, flags); uint32_t header = 0; + if (!mp3->xing_toc) + return AVERROR(ENOSYS); + if (ret < 0) return ret; @@ -270,6 +280,7 @@ AVInputFormat ff_mp3_demuxer = { .read_header = mp3_read_header, .read_packet = mp3_read_packet, .read_seek = mp3_seek, + .priv_data_size = sizeof(MP3DecContext), .flags = AVFMT_GENERIC_INDEX, .extensions = "mp2,mp3,m2a", /* XXX: use probe */ };