From bf3998d71efa7a9a6acc6d7d81dd674249e074c1 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Fri, 16 Mar 2012 14:04:00 -0700 Subject: [PATCH] mimic: don't use self as reference, and report completion at end of decode(). Fixes hangs on corrupt samples that reference self-frames. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit 80387f0e2568746dce4a68e2217297029a053dae) Signed-off-by: Reinhard Tartler --- libavcodec/mimic.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/libavcodec/mimic.c b/libavcodec/mimic.c index b93f51fa3e..fd03b97c37 100644 --- a/libavcodec/mimic.c +++ b/libavcodec/mimic.c @@ -259,8 +259,8 @@ static int decode(MimicContext *ctx, int quality, int num_coeffs, int index = (ctx->cur_index+backref)&15; uint8_t *p = ctx->flipped_ptrs[index].data[0]; - ff_thread_await_progress(&ctx->buf_ptrs[index], cur_row, 0); - if(p) { + if (index != ctx->cur_index && p) { + ff_thread_await_progress(&ctx->buf_ptrs[index], cur_row, 0); p += src - ctx->flipped_ptrs[ctx->prev_index].data[plane]; ctx->dsp.put_pixels_tab[1][0](dst, p, stride, 8); @@ -310,6 +310,7 @@ static int mimic_decode_frame(AVCodecContext *avctx, void *data, int width, height; int quality, num_coeffs; int swap_buf_size = buf_size - MIMIC_HEADER_SIZE; + int res; if(buf_size < MIMIC_HEADER_SIZE) { av_log(avctx, AV_LOG_ERROR, "insufficient data\n"); @@ -377,10 +378,10 @@ static int mimic_decode_frame(AVCodecContext *avctx, void *data, swap_buf_size>>2); init_get_bits(&ctx->gb, ctx->swap_buf, swap_buf_size << 3); - if(!decode(ctx, quality, num_coeffs, !is_pframe)) { - if (avctx->active_thread_type&FF_THREAD_FRAME) - ff_thread_report_progress(&ctx->buf_ptrs[ctx->cur_index], INT_MAX, 0); - else { + res = decode(ctx, quality, num_coeffs, !is_pframe); + ff_thread_report_progress(&ctx->buf_ptrs[ctx->cur_index], INT_MAX, 0); + if (!res) { + if (!(avctx->active_thread_type & FF_THREAD_FRAME)) { ff_thread_release_buffer(avctx, &ctx->buf_ptrs[ctx->cur_index]); return -1; }