diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2013-04-16 19:53:24 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2013-05-09 21:42:40 +0200 |
commit | 840931e76608d6b242fd416c42cd88a10bb0e42a (patch) | |
tree | d8f4c1fc64de7c1a2fa25b0762eab273202913fc | |
parent | 1ce3f736d2aa531af362d75f675efb11e36c5172 (diff) | |
download | ffmpeg-840931e76608d6b242fd416c42cd88a10bb0e42a.tar.gz |
mjpegdec: fix overlapping memcpy with upscale_v
Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit b39fd7d63648442c20671c3e4b357268ec5c49f2)
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | libavcodec/mjpegdec.c | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c index 54090e58d3..f1e9b6809b 100644 --- a/libavcodec/mjpegdec.c +++ b/libavcodec/mjpegdec.c @@ -1639,6 +1639,7 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, MJpegDecodeContext *s = avctx->priv_data; const uint8_t *buf_end, *buf_ptr; const uint8_t *unescaped_buf_ptr; + int hshift, vshift; int unescaped_buf_size; int start_code; int i, index; @@ -1817,6 +1818,9 @@ the_end: } if (s->upscale_v) { uint8_t *dst = &((uint8_t *)s->picture_ptr->data[s->upscale_v])[(s->height - 1) * s->linesize[s->upscale_v]]; + int w; + avcodec_get_chroma_sub_sample(s->avctx->pix_fmt, &hshift, &vshift); + w = s->width >> hshift; av_assert0(avctx->pix_fmt == AV_PIX_FMT_YUVJ444P || avctx->pix_fmt == AV_PIX_FMT_YUV444P || avctx->pix_fmt == AV_PIX_FMT_YUVJ422P || @@ -1825,16 +1829,16 @@ the_end: uint8_t *src1 = &((uint8_t *)s->picture_ptr->data[s->upscale_v])[i / 2 * s->linesize[s->upscale_v]]; uint8_t *src2 = &((uint8_t *)s->picture_ptr->data[s->upscale_v])[(i + 1) / 2 * s->linesize[s->upscale_v]]; if (src1 == src2) { - memcpy(dst, src1, s->width); + memcpy(dst, src1, w); } else { - for (index = 0; index < s->width; index++) + for (index = 0; index < w; index++) dst[index] = (src1[index] + src2[index]) >> 1; } dst -= s->linesize[s->upscale_v]; } } if (s->flipped && (s->avctx->flags & CODEC_FLAG_EMU_EDGE)) { - int hshift, vshift, j; + int j; avcodec_get_chroma_sub_sample(s->avctx->pix_fmt, &hshift, &vshift); for (index=0; index<4; index++) { uint8_t *dst = s->picture_ptr->data[index]; |