diff options
author | Anton Khirnov <anton@khirnov.net> | 2014-08-03 10:14:48 +0200 |
---|---|---|
committer | Anton Khirnov <anton@khirnov.net> | 2014-08-06 19:22:05 +0000 |
commit | 9d5f4f025304ac7c69775179044e6f69f370441a (patch) | |
tree | 919c94bd3acc5df927146d905e3ed3eb8e377e7e | |
parent | cf6b2a0ad2b06aabf04bec4c7b19e78a560cd904 (diff) | |
download | ffmpeg-9d5f4f025304ac7c69775179044e6f69f370441a.tar.gz |
svq1: do not modify the input packet
The input data must remain constant, make a copy instead. This is in
theory a performance hit, but since I failed to find any samples
using this feature, this should not matter in practice.
Also, check the size of the header, avoiding invalid reads on truncated
data.
CC:libav-stable@libav.org
(cherry picked from commit 7b588bb691644e1b3c168b99accf74248a24e3cf)
Signed-off-by: Anton Khirnov <anton@khirnov.net>
Conflicts:
libavcodec/svq1dec.c
-rw-r--r-- | libavcodec/mpegvideo.h | 3 | ||||
-rw-r--r-- | libavcodec/svq1dec.c | 28 |
2 files changed, 26 insertions, 5 deletions
diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h index 06be735301..1c08c8744d 100644 --- a/libavcodec/mpegvideo.h +++ b/libavcodec/mpegvideo.h @@ -679,6 +679,9 @@ typedef struct MpegEncContext { int (*dct_quantize)(struct MpegEncContext *s, DCTELEM *block/*align 16*/, int n, int qscale, int *overflow); int (*fast_dct_quantize)(struct MpegEncContext *s, DCTELEM *block/*align 16*/, int n, int qscale, int *overflow); void (*denoise_dct)(struct MpegEncContext *s, DCTELEM *block); + + uint8_t *pkt_swapped; + int pkt_swapped_allocated; } MpegEncContext; #define REBASE_PICTURE(pic, new_ctx, old_ctx) (pic ? \ diff --git a/libavcodec/svq1dec.c b/libavcodec/svq1dec.c index 1cbf1f51c9..4acb7ce730 100644 --- a/libavcodec/svq1dec.c +++ b/libavcodec/svq1dec.c @@ -644,13 +644,29 @@ static int svq1_decode_frame(AVCodecContext *avctx, return -1; /* swap some header bytes (why?) */ - if (s->f_code != 0x20) { - uint32_t *src = (uint32_t *) (buf + 4); + if (s->f_code != 0x20) { + uint32_t *src; - for (i=0; i < 4; i++) { - src[i] = ((src[i] << 16) | (src[i] >> 16)) ^ src[7 - i]; + if (buf_size < 9 * 4) { + av_log(avctx, AV_LOG_ERROR, "Input packet too small\n"); + return AVERROR_INVALIDDATA; + } + + av_fast_malloc(s->pkt_swapped, &s->pkt_swapped_allocated, + buf_size); + if (!s->pkt_swapped) + return AVERROR(ENOMEM); + + memcpy(s->pkt_swapped, buf, buf_size); + buf = s->pkt_swapped; + init_get_bits(&s->gb, buf, buf_size * 8); + skip_bits(&s->gb, 22); + + src = (uint32_t *)(s->pkt_swapped + 4); + + for (i = 0; i < 4; i++) + src[i] = ((src[i] << 16) | (src[i] >> 16)) ^ src[7 - i]; } - } result = svq1_decode_frame_header (&s->gb, s); @@ -804,6 +820,8 @@ static av_cold int svq1_decode_end(AVCodecContext *avctx) { MpegEncContext *s = avctx->priv_data; + av_freep(&s->pkt_swapped); + MPV_common_end(s); return 0; } |