From 5a6af4fd74a4fcadf76cbe28634274d67a07cfad Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Fri, 17 May 2013 18:28:33 +0200 Subject: [PATCH 01/17] wavpack: return meaningful errors And forward those that were already meaningful. (cherry picked from commit 8c34558131d846d2b10389564caadaa206372fd4) Signed-off-by: Reinhard Tartler Conflicts: libavcodec/wavpack.c --- libavcodec/wavpack.c | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c index 59d735fab5..31377e75c6 100644 --- a/libavcodec/wavpack.c +++ b/libavcodec/wavpack.c @@ -773,13 +773,13 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, if (block_no >= wc->fdec_num && wv_alloc_frame_context(wc) < 0) { av_log(avctx, AV_LOG_ERROR, "Error creating frame decode context\n"); - return -1; + return AVERROR_INVALIDDATA; } s = wc->fdec[block_no]; if (!s) { av_log(avctx, AV_LOG_ERROR, "Context for block %d is not present\n", block_no); - return -1; + return AVERROR_INVALIDDATA; } memset(s->decorr, 0, MAX_TERMS * sizeof(Decorr)); @@ -1021,7 +1021,7 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, case WP_ID_CHANINFO: if (size <= 1) { av_log(avctx, AV_LOG_ERROR, "Insufficient channel information\n"); - return -1; + return AVERROR_INVALIDDATA; } chan = *buf++; switch (size - 2) { @@ -1040,10 +1040,11 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, chmask = avctx->channel_layout; } if (chan != avctx->channels) { - av_log(avctx, AV_LOG_ERROR, "Block reports total %d channels, " - "decoder believes it's %d channels\n", chan, - avctx->channels); - return -1; + av_log(avctx, AV_LOG_ERROR, + "Block reports total %d channels, " + "decoder believes it's %d channels\n", + chan, avctx->channels); + return AVERROR_INVALIDDATA; } if (!avctx->channel_layout) avctx->channel_layout = chmask; @@ -1058,31 +1059,31 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, if (!got_terms) { av_log(avctx, AV_LOG_ERROR, "No block with decorrelation terms\n"); - return -1; + return AVERROR_INVALIDDATA; } if (!got_weights) { av_log(avctx, AV_LOG_ERROR, "No block with decorrelation weights\n"); - return -1; + return AVERROR_INVALIDDATA; } if (!got_samples) { av_log(avctx, AV_LOG_ERROR, "No block with decorrelation samples\n"); - return -1; + return AVERROR_INVALIDDATA; } if (!got_entropy) { av_log(avctx, AV_LOG_ERROR, "No block with entropy info\n"); - return -1; + return AVERROR_INVALIDDATA; } if (s->hybrid && !got_hybrid) { av_log(avctx, AV_LOG_ERROR, "Hybrid config not found\n"); - return -1; + return AVERROR_INVALIDDATA; } if (!got_bs) { av_log(avctx, AV_LOG_ERROR, "Packed samples not found\n"); - return -1; + return AVERROR_INVALIDDATA; } if (!got_float && avctx->sample_fmt == AV_SAMPLE_FMT_FLT) { av_log(avctx, AV_LOG_ERROR, "Float information not found\n"); - return -1; + return AVERROR_INVALIDDATA; } if (s->got_extra_bits && avctx->sample_fmt != AV_SAMPLE_FMT_FLT) { const int size = get_bits_left(&s->gb_extra_bits); @@ -1102,7 +1103,7 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, samplecount = wv_unpack_stereo(s, &s->gb, samples, AV_SAMPLE_FMT_FLT); if (samplecount < 0) - return -1; + return samplecount; samplecount >>= 1; } else { @@ -1116,7 +1117,7 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, samplecount = wv_unpack_mono(s, &s->gb, samples, AV_SAMPLE_FMT_FLT); if (samplecount < 0) - return -1; + return samplecount; if (s->stereo && avctx->sample_fmt == AV_SAMPLE_FMT_S16) { int16_t *dst = (int16_t*)samples + 1; @@ -1193,7 +1194,7 @@ static int wavpack_decode_frame(AVCodecContext *avctx, void *data, if (s->samples <= 0) { av_log(avctx, AV_LOG_ERROR, "Invalid number of samples: %d\n", s->samples); - return AVERROR(EINVAL); + return AVERROR_INVALIDDATA; } if (frame_flags & 0x80) { @@ -1227,13 +1228,13 @@ static int wavpack_decode_frame(AVCodecContext *avctx, void *data, av_log(avctx, AV_LOG_ERROR, "Block %d has invalid size (size %d " "vs. %d bytes left)\n", s->block, frame_size, buf_size); wavpack_decode_flush(avctx); - return -1; + return AVERROR_INVALIDDATA; } if ((samplecount = wavpack_decode_block(avctx, s->block, s->frame.data[0], got_frame_ptr, buf, frame_size)) < 0) { wavpack_decode_flush(avctx); - return -1; + return samplecount; } s->block++; buf += frame_size; buf_size -= frame_size; From ea7ba1d8717dacca70771d0fbe553acbdbd47739 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 29 May 2013 16:18:40 +0200 Subject: [PATCH 02/17] apetag: use int64_t for filesize CC: libav-stable@libav.org (cherry picked from commit e816aaacd68201b67182f9c70dc680e89a0123e9) Signed-off-by: Reinhard Tartler --- libavformat/apetag.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/apetag.c b/libavformat/apetag.c index 257ed48970..2390bfaad3 100644 --- a/libavformat/apetag.c +++ b/libavformat/apetag.c @@ -65,7 +65,7 @@ static int ape_tag_read_field(AVFormatContext *s) void ff_ape_parse_tag(AVFormatContext *s) { AVIOContext *pb = s->pb; - int file_size = avio_size(pb); + int64_t file_size = avio_size(pb); uint32_t val, fields, tag_bytes; uint8_t buf[8]; int i; From 96de1c5ed90b4defb4126d946061d4a23101b28c Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Mon, 3 Jun 2013 04:53:02 +0200 Subject: [PATCH 03/17] tiff: do not overread the source buffer At least 2 bytes from the source are read every loop. Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit 9c2216976907336dfae0e8e38a4d70ca2465a92c) Signed-off-by: Reinhard Tartler Conflicts: libavcodec/tiff.c --- libavcodec/tiff.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c index a0db1f1d28..8a1db12aae 100644 --- a/libavcodec/tiff.c +++ b/libavcodec/tiff.c @@ -186,10 +186,13 @@ static int tiff_unpack_strip(TiffContext *s, uint8_t* dst, int stride, const uin break; case TIFF_PACKBITS: for(pixels = 0; pixels < width;){ + if (ssrc + size - src < 2) + return AVERROR_INVALIDDATA; code = (int8_t)*src++; if(code >= 0){ code++; - if(pixels + code > width){ + if (pixels + code > width || + ssrc + size - src < code) { av_log(s->avctx, AV_LOG_ERROR, "Copy went out of bounds\n"); return -1; } From e98f95670bf107a4307258b33e37be0abe811279 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 29 May 2013 16:18:40 +0200 Subject: [PATCH 04/17] Prepare for 0.8.8 Release --- RELEASE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RELEASE b/RELEASE index 1e9b46b229..6201b5f77f 100644 --- a/RELEASE +++ b/RELEASE @@ -1 +1 @@ -0.8.7 +0.8.8 From e96aaa5622ed2efeb3729f46331990d952208a17 Mon Sep 17 00:00:00 2001 From: Kostya Shishkov Date: Wed, 12 Jun 2013 14:22:24 +0200 Subject: [PATCH 05/17] smacker: fix an off by one in huff.length computation Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org Signed-off-by: Luca Barbato (cherry picked from commit ee205588b250fe5cae0681be8eba51a5403c3272) Signed-off-by: Luca Barbato --- libavcodec/smacker.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/smacker.c b/libavcodec/smacker.c index 3928d8f569..f74f0dbc54 100644 --- a/libavcodec/smacker.c +++ b/libavcodec/smacker.c @@ -252,7 +252,7 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int ctx.recode2 = tmp2.values; ctx.last = last; - huff.length = ((size + 3) >> 2) + 3; + huff.length = ((size + 3) >> 2) + 4; huff.maxlength = 0; huff.current = 0; huff.values = av_mallocz(huff.length * sizeof(int)); From d7b7b10518ccd638131ef41062e1bc0c608628f7 Mon Sep 17 00:00:00 2001 From: Kostya Shishkov Date: Wed, 12 Jun 2013 14:27:00 +0200 Subject: [PATCH 06/17] smacker: check the return value of smacker_decode_tree Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org Signed-off-by: Luca Barbato (cherry picked from commit a2f9937bb04b23a341b0ec0eb1d923bbeb420277) Signed-off-by: Luca Barbato --- libavcodec/smacker.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/libavcodec/smacker.c b/libavcodec/smacker.c index f74f0dbc54..e9192ffd0c 100644 --- a/libavcodec/smacker.c +++ b/libavcodec/smacker.c @@ -648,7 +648,16 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, h[i].lengths = av_mallocz(256 * sizeof(int)); h[i].values = av_mallocz(256 * sizeof(int)); skip_bits1(&gb); - smacker_decode_tree(&gb, &h[i], 0, 0); + if (smacker_decode_tree(&gb, &h[i], 0, 0) < 0) { + for (; i >= 0; i--) { + if (vlc[i].table) + ff_free_vlc(&vlc[i]); + av_free(h[i].bits); + av_free(h[i].lengths); + av_free(h[i].values); + } + return AVERROR_INVALIDDATA; + } skip_bits1(&gb); if(h[i].current > 1) { res = init_vlc(&vlc[i], SMKTREE_BITS, h[i].length, From db0c8061fe540bbd72146cc0c9105e30d54d7f61 Mon Sep 17 00:00:00 2001 From: Kostya Shishkov Date: Wed, 12 Jun 2013 14:28:07 +0200 Subject: [PATCH 07/17] smacker: pad the extradata allocation Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org Signed-off-by: Luca Barbato (cherry picked from commit 4c22baf65363433f8c20efd1022b4ba2d8cf2288) Signed-off-by: Luca Barbato --- libavformat/smacker.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavformat/smacker.c b/libavformat/smacker.c index 6df8b8b619..e7c89e09f9 100644 --- a/libavformat/smacker.c +++ b/libavformat/smacker.c @@ -203,7 +203,8 @@ static int smacker_read_header(AVFormatContext *s, AVFormatParameters *ap) /* load trees to extradata, they will be unpacked by decoder */ - st->codec->extradata = av_malloc(smk->treesize + 16); + st->codec->extradata = av_mallocz(smk->treesize + 16 + + FF_INPUT_BUFFER_PADDING_SIZE); st->codec->extradata_size = smk->treesize + 16; if(!st->codec->extradata){ av_log(s, AV_LOG_ERROR, "Cannot allocate %i bytes of extradata\n", smk->treesize + 16); From b40870e636401ddbc97f966a60a21780e1eb17ca Mon Sep 17 00:00:00 2001 From: Kostya Shishkov Date: Wed, 12 Jun 2013 14:30:51 +0200 Subject: [PATCH 08/17] smacker: check frame size validity Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org Signed-off-by: Luca Barbato (cherry picked from commit 07423ad7836325e03894f2f87ba46a531a1cc0b3) Signed-off-by: Luca Barbato --- libavformat/smacker.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libavformat/smacker.c b/libavformat/smacker.c index e7c89e09f9..d6bb21373e 100644 --- a/libavformat/smacker.c +++ b/libavformat/smacker.c @@ -297,10 +297,14 @@ static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt) /* if audio chunks are present, put them to stack and retrieve later */ for(i = 0; i < 7; i++) { if(flags & 1) { - int size; + uint32_t size; uint8_t *tmpbuf; size = avio_rl32(s->pb) - 4; + if (!size || size > frame_size) { + av_log(s, AV_LOG_ERROR, "Invalid audio part size\n"); + return AVERROR_INVALIDDATA; + } frame_size -= size; frame_size -= 4; smk->curstream++; From 9248f789d1fa8e12ea2fd3073d7bb5cd13d654a6 Mon Sep 17 00:00:00 2001 From: Alexandra Khirnova Date: Wed, 13 Mar 2013 13:54:27 +0100 Subject: [PATCH 09/17] vmdav: convert to bytestream2 Signed-off-by: Anton Khirnov (cherry picked from commit 0afcf97e1ece51d29bb791698b00cd1b7ba97dcf) Signed-off-by: Reinhard Tartler Conflicts: libavcodec/vmdav.c --- libavcodec/vmdav.c | 152 ++++++++++++++++++--------------------------- 1 file changed, 59 insertions(+), 93 deletions(-) diff --git a/libavcodec/vmdav.c b/libavcodec/vmdav.c index 570c362a57..4659971335 100644 --- a/libavcodec/vmdav.c +++ b/libavcodec/vmdav.c @@ -45,6 +45,7 @@ #include "libavutil/intreadwrite.h" #include "avcodec.h" +#include "bytestream.h" #define VMD_HEADER_SIZE 0x330 #define PALETTE_COUNT 256 @@ -75,8 +76,6 @@ typedef struct VmdVideoContext { static void lz_unpack(const unsigned char *src, int src_len, unsigned char *dest, int dest_len) { - const unsigned char *s; - unsigned int s_len; unsigned char *d; unsigned char *d_end; unsigned char queue[QUEUE_SIZE]; @@ -87,18 +86,17 @@ static void lz_unpack(const unsigned char *src, int src_len, unsigned int speclen; unsigned char tag; unsigned int i, j; + GetByteContext gb; - s = src; - s_len = src_len; + bytestream2_init(&gb, src, src_len); d = dest; d_end = d + dest_len; - dataleft = AV_RL32(s); - s += 4; s_len -= 4; + dataleft = bytestream2_get_le32(&gb); memset(queue, 0x20, QUEUE_SIZE); - if (s_len < 4) + if (bytestream2_get_bytes_left(&gb) < 4) return; - if (AV_RL32(s) == 0x56781234) { - s += 4; s_len -= 4; + if (bytestream2_peek_le32(&gb) == 0x56781234) { + bytestream2_get_le32(&gb); qpos = 0x111; speclen = 0xF + 3; } else { @@ -106,40 +104,32 @@ static void lz_unpack(const unsigned char *src, int src_len, speclen = 100; /* no speclen */ } - while (dataleft > 0 && s_len > 0) { - tag = *s++; s_len--; + while (dataleft > 0 && bytestream2_get_bytes_left(&gb) > 0) { + tag = bytestream2_get_byteu(&gb); if ((tag == 0xFF) && (dataleft > 8)) { - if (d + 8 > d_end || s_len < 8) + if (d + 8 > d_end || bytestream2_get_bytes_left(&gb) < 8) return; for (i = 0; i < 8; i++) { - queue[qpos++] = *d++ = *s++; + queue[qpos++] = *d++ = bytestream2_get_byteu(&gb); qpos &= QUEUE_MASK; } - s_len -= 8; dataleft -= 8; } else { for (i = 0; i < 8; i++) { if (dataleft == 0) break; if (tag & 0x01) { - if (d + 1 > d_end || s_len < 1) + if (d + 1 > d_end || bytestream2_get_bytes_left(&gb) < 1) return; - queue[qpos++] = *d++ = *s++; + queue[qpos++] = *d++ = bytestream2_get_byte(&gb); qpos &= QUEUE_MASK; dataleft--; - s_len--; } else { - if (s_len < 2) - return; - chainofs = *s++; - chainofs |= ((*s & 0xF0) << 4); - chainlen = (*s++ & 0x0F) + 3; - s_len -= 2; + chainofs = bytestream2_get_byte(&gb); + chainofs |= ((bytestream2_peek_byte(&gb) & 0xF0) << 4); + chainlen = (bytestream2_get_byte(&gb) & 0x0F) + 3; if (chainlen == speclen) { - if (s_len < 1) - return; - chainlen = *s++ + 0xF + 3; - s_len--; + chainlen = bytestream2_get_byte(&gb) + 0xF + 3; } if (d + chainlen > d_end) return; @@ -159,49 +149,44 @@ static void lz_unpack(const unsigned char *src, int src_len, static int rle_unpack(const unsigned char *src, unsigned char *dest, int src_count, int src_size, int dest_len) { - const unsigned char *ps; unsigned char *pd; int i, l; unsigned char *dest_end = dest + dest_len; + GetByteContext gb; - ps = src; + bytestream2_init(&gb, src, src_size); pd = dest; if (src_count & 1) { - if (src_size < 1) + if (bytestream2_get_bytes_left(&gb) < 1) return 0; - *pd++ = *ps++; - src_size--; + *pd++ = bytestream2_get_byteu(&gb); } src_count >>= 1; i = 0; do { - if (src_size < 1) + if (bytestream2_get_bytes_left(&gb) < 1) break; - l = *ps++; - src_size--; + l = bytestream2_get_byteu(&gb); if (l & 0x80) { l = (l & 0x7F) * 2; - if (pd + l > dest_end || src_size < l) - return ps - src; - memcpy(pd, ps, l); - ps += l; - src_size -= l; + if (pd + l > dest_end || bytestream2_get_bytes_left(&gb) < l) + return bytestream2_tell(&gb); + bytestream2_get_buffer(&gb, pd, l); pd += l; } else { - if (pd + i > dest_end || src_size < 2) - return ps - src; + if (pd + i > dest_end || bytestream2_get_bytes_left(&gb) < 2) + return bytestream2_tell(&gb); for (i = 0; i < l; i++) { - *pd++ = ps[0]; - *pd++ = ps[1]; + *pd++ = bytestream2_get_byteu(&gb); + *pd++ = bytestream2_get_byteu(&gb); } - ps += 2; - src_size -= 2; + bytestream2_skip(&gb, 2); } i += l; } while (i < src_count); - return ps - src; + return bytestream2_tell(&gb); } static void vmd_decode(VmdVideoContext *s) @@ -210,11 +195,8 @@ static void vmd_decode(VmdVideoContext *s) unsigned int *palette32; unsigned char r, g, b; - /* point to the start of the encoded data */ - const unsigned char *p = s->buf + 16; + GetByteContext gb; - const unsigned char *pb; - unsigned int pb_size; unsigned char meth; unsigned char *dp; /* pointer to current frame */ unsigned char *pp; /* pointer to previous frame */ @@ -259,30 +241,31 @@ static void vmd_decode(VmdVideoContext *s) } /* check if there is a new palette */ + bytestream2_init(&gb, s->buf + 16, s->size - 16); if (s->buf[15] & 0x02) { - p += 2; + bytestream2_skip(&gb, 2); palette32 = (unsigned int *)s->palette; - for (i = 0; i < PALETTE_COUNT; i++) { - r = *p++ * 4; - g = *p++ * 4; - b = *p++ * 4; - palette32[i] = (r << 16) | (g << 8) | (b); + if (bytestream2_get_bytes_left(&gb) >= PALETTE_COUNT * 3) { + for (i = 0; i < PALETTE_COUNT; i++) { + r = bytestream2_get_byteu(&gb) * 4; + g = bytestream2_get_byteu(&gb) * 4; + b = bytestream2_get_byteu(&gb) * 4; + palette32[i] = (r << 16) | (g << 8) | (b); + } } s->size -= (256 * 3 + 2); } if (s->size > 0) { /* originally UnpackFrame in VAG's code */ - pb = p; - pb_size = s->buf + s->size - pb; - if (pb_size < 1) + bytestream2_init(&gb, gb.buffer, s->buf + s->size - gb.buffer); + if (bytestream2_get_bytes_left(&gb) < 1) return; - meth = *pb++; pb_size--; + meth = bytestream2_get_byteu(&gb); if (meth & 0x80) { - lz_unpack(pb, pb_size, + lz_unpack(gb.buffer, bytestream2_get_bytes_left(&gb), s->unpack_buffer, s->unpack_buffer_size); meth &= 0x7F; - pb = s->unpack_buffer; - pb_size = s->unpack_buffer_size; + bytestream2_init(&gb, s->unpack_buffer, s->unpack_buffer_size); } dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x]; @@ -292,17 +275,12 @@ static void vmd_decode(VmdVideoContext *s) for (i = 0; i < frame_height; i++) { ofs = 0; do { - if (pb_size < 1) - return; - len = *pb++; - pb_size--; + len = bytestream2_get_byte(&gb); if (len & 0x80) { len = (len & 0x7F) + 1; - if (ofs + len > frame_width || pb_size < len) + if (ofs + len > frame_width || bytestream2_get_bytes_left(&gb) < len) return; - memcpy(&dp[ofs], pb, len); - pb += len; - pb_size -= len; + bytestream2_get_buffer(&gb, &dp[ofs], len); ofs += len; } else { /* interframe pixel copy */ @@ -324,11 +302,7 @@ static void vmd_decode(VmdVideoContext *s) case 2: for (i = 0; i < frame_height; i++) { - if (pb_size < frame_width) - return; - memcpy(dp, pb, frame_width); - pb += frame_width; - pb_size -= frame_width; + bytestream2_get_buffer(&gb, dp, frame_width); dp += s->frame.linesize[0]; pp += s->prev_frame.linesize[0]; } @@ -338,24 +312,16 @@ static void vmd_decode(VmdVideoContext *s) for (i = 0; i < frame_height; i++) { ofs = 0; do { - if (pb_size < 1) - return; - len = *pb++; - pb_size--; + len = bytestream2_get_byte(&gb); if (len & 0x80) { len = (len & 0x7F) + 1; - if (pb_size < 1) - return; - if (*pb++ == 0xFF) - len = rle_unpack(pb, &dp[ofs], len, pb_size, frame_width - ofs); - else { - if (pb_size < len) - return; - memcpy(&dp[ofs], pb, len); - } - pb += len; - pb_size -= 1 + len; - ofs += len; + if (bytestream2_get_byte(&gb) == 0xFF) + len = rle_unpack(gb.buffer, &dp[ofs], + len, bytestream2_get_bytes_left(&gb), + frame_width - ofs); + else + bytestream2_get_buffer(&gb, &dp[ofs], len); + bytestream2_skip(&gb, len); } else { /* interframe pixel copy */ if (ofs + len + 1 > frame_width || !s->prev_frame.data[0]) From 078e68d2617fcb339896ca68503a06f07cfdb41f Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Tue, 13 Nov 2012 22:10:54 +0100 Subject: [PATCH 10/17] 4xm: don't rely on get_buffer() initializing the frame. (cherry picked from commit b047c68783aa4042b322af7af043b643d5daf09c) Signed-off-by: Reinhard Tartler --- libavcodec/4xm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavcodec/4xm.c b/libavcodec/4xm.c index 0d4f036b3a..c210e46e13 100644 --- a/libavcodec/4xm.c +++ b/libavcodec/4xm.c @@ -807,6 +807,7 @@ static int decode_frame(AVCodecContext *avctx, av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return -1; } + memset(f->last_picture.data[0], 0, avctx->height * FFABS(f->last_picture.linesize[0])); } p->pict_type= AV_PICTURE_TYPE_P; From e797b7787b258be7561939904442165510f381a6 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 13 Feb 2013 20:46:08 +0100 Subject: [PATCH 11/17] 4xm: check the return value of read_huffman_tables(). CC:libav-stable@libav.org (cherry picked from commit 8097fc9a2dd49d8e467b16c8bafaa96242b7fe46) Signed-off-by: Reinhard Tartler (cherry picked from commit bb3f1cad171b31537b64a9d19cabdbff50aca260) Signed-off-by: Reinhard Tartler Conflicts: libavcodec/4xm.c --- libavcodec/4xm.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libavcodec/4xm.c b/libavcodec/4xm.c index c210e46e13..efaf939062 100644 --- a/libavcodec/4xm.c +++ b/libavcodec/4xm.c @@ -679,7 +679,11 @@ static int decode_i_frame(FourXContext *f, const uint8_t *buf, int length){ return -1; } - prestream= read_huffman_tables(f, prestream); + prestream = read_huffman_tables(f, prestream); + if (!prestream) { + av_log(f->avctx, AV_LOG_ERROR, "Error reading Huffman tables.\n"); + return AVERROR_INVALIDDATA; + } init_get_bits(&f->gb, buf + 4, 8*bitstream_size); From 284ac9191b755ffce1475687b597a8a738d511c6 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Wed, 5 Jun 2013 17:12:16 +0200 Subject: [PATCH 12/17] 4xm: use the correct logging context (cherry picked from commit 08859d19b429c522d6494c186656f4a2d3ff8e21) Signed-off-by: Luca Barbato Conflicts: libavcodec/4xm.c --- libavcodec/4xm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/4xm.c b/libavcodec/4xm.c index efaf939062..735cfcf73a 100644 --- a/libavcodec/4xm.c +++ b/libavcodec/4xm.c @@ -633,8 +633,8 @@ static int decode_i2_frame(FourXContext *f, const uint8_t *buf, int length){ color[0]= bytestream2_get_le16u(&g3); color[1]= bytestream2_get_le16u(&g3); - if(color[0]&0x8000) av_log(NULL, AV_LOG_ERROR, "unk bit 1\n"); - if(color[1]&0x8000) av_log(NULL, AV_LOG_ERROR, "unk bit 2\n"); + if(color[0]&0x8000) av_log(f->avctx, AV_LOG_ERROR, "unk bit 1\n"); + if(color[1]&0x8000) av_log(f->avctx, AV_LOG_ERROR, "unk bit 2\n"); color[2]= mix(color[0], color[1]); color[3]= mix(color[1], color[0]); From e5679444fd60d0b5a32ad4233e65d3a85300a952 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Thu, 6 Jun 2013 16:58:57 +0200 Subject: [PATCH 13/17] 4xm: reject frames not compatible with the declared version Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit 145023f57262d21474e35b4a6069cf95136339d4) Signed-off-by: Luca Barbato Conflicts: libavcodec/4xm.c --- libavcodec/4xm.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libavcodec/4xm.c b/libavcodec/4xm.c index 735cfcf73a..842e787baa 100644 --- a/libavcodec/4xm.c +++ b/libavcodec/4xm.c @@ -769,6 +769,9 @@ static int decode_frame(AVCodecContext *avctx, av_log(f->avctx, AV_LOG_ERROR, "cframe id mismatch %d %d\n", id, avctx->frame_number); } + if (f->version <= 1) + return AVERROR_INVALIDDATA; + cfrm->size= cfrm->id= 0; frame_4cc= AV_RL32("pfrm"); }else From 6a4f1e784e39c82194a485995906d9917d4619b2 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Mon, 10 Jun 2013 16:37:43 +0200 Subject: [PATCH 14/17] 4xm: check bitstream_size boundary before using it Prevent buffer overread. Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit 59d7bb99b6a963b7e11c637228b2203adf535eee) Signed-off-by: Reinhard Tartler Conflicts: libavcodec/4xm.c --- libavcodec/4xm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libavcodec/4xm.c b/libavcodec/4xm.c index 842e787baa..e9f08c3729 100644 --- a/libavcodec/4xm.c +++ b/libavcodec/4xm.c @@ -663,6 +663,9 @@ static int decode_i_frame(FourXContext *f, const uint8_t *buf, int length){ unsigned int prestream_size; const uint8_t *prestream; + if (bitstream_size > (1 << 26)) + return AVERROR_INVALIDDATA; + if (length < bitstream_size + 12) { av_log(f->avctx, AV_LOG_ERROR, "packet size too small\n"); return AVERROR_INVALIDDATA; @@ -673,7 +676,6 @@ static int decode_i_frame(FourXContext *f, const uint8_t *buf, int length){ prestream = buf + bitstream_size + 12; if(prestream_size + bitstream_size + 12 != length - || bitstream_size > (1<<26) || prestream_size > (1<<26)){ av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %d %d\n", prestream_size, bitstream_size, length); return -1; From 0c943d1cdd18d0aea4ebc15f18a1152f7a77e5c9 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Sun, 9 Jun 2013 18:27:05 +0200 Subject: [PATCH 15/17] 4xm: do not overread the source buffer in decode_p_block Check for out of picture macroblocks before calling mcdc. Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit 94aefb1932be882fd93f66cf790ceb19ff575c19) Signed-off-by: Reinhard Tartler Conflicts: libavcodec/4xm.c --- libavcodec/4xm.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libavcodec/4xm.c b/libavcodec/4xm.c index e9f08c3729..77d15d5803 100644 --- a/libavcodec/4xm.c +++ b/libavcodec/4xm.c @@ -343,6 +343,10 @@ static void decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src, int lo decode_p_block(f, dst , src , log2w, log2h, stride); decode_p_block(f, dst + (1<version<2){ + if (start > src || src > end) { + av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n"); + return; + } mcdc(dst, src, log2w, h, stride, 1, 0); }else if(code == 4){ src += f->mv[bytestream2_get_byte(&f->g)]; @@ -352,6 +356,10 @@ static void decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src, int lo } mcdc(dst, src, log2w, h, stride, 1, bytestream2_get_le16(&f->g2)); }else if(code == 5){ + if (start > src || src > end) { + av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n"); + return; + } mcdc(dst, src, log2w, h, stride, 0, bytestream2_get_le16(&f->g2)); }else if(code == 6){ if(log2w){ From b20004b2e6165a6d5ef6bc6ae98d3d33c6460808 Mon Sep 17 00:00:00 2001 From: Reinhard Tartler Date: Sat, 6 Jul 2013 09:46:07 +0200 Subject: [PATCH 16/17] lavc: move put_bits_left in put_bits.h (cherry picked from commit afe03092dd693d025d43e1620283d8d285c92772) Signed-off-by: Reinhard Tartler Conflicts: libavcodec/dv.c --- libavcodec/dv.c | 5 ----- libavcodec/put_bits.h | 8 ++++++++ 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/libavcodec/dv.c b/libavcodec/dv.c index 03a05b3748..6f74e7b5bd 100644 --- a/libavcodec/dv.c +++ b/libavcodec/dv.c @@ -372,11 +372,6 @@ typedef struct BlockInfo { static const int vs_total_ac_bits = (100 * 4 + 68*2) * 5; static const int mb_area_start[5] = { 1, 6, 21, 43, 64 }; -static inline int put_bits_left(PutBitContext* s) -{ - return (s->buf_end - s->buf) * 8 - put_bits_count(s); -} - /* decode AC coefficients */ static void dv_decode_ac(GetBitContext *gb, BlockInfo *mb, DCTELEM *block) { diff --git a/libavcodec/put_bits.h b/libavcodec/put_bits.h index 6e812670b8..905461a725 100644 --- a/libavcodec/put_bits.h +++ b/libavcodec/put_bits.h @@ -72,6 +72,14 @@ static inline int put_bits_count(PutBitContext *s) return (s->buf_ptr - s->buf) * 8 + 32 - s->bit_left; } +/** + * @return the number of bits available in the bitstream. + */ +static inline int put_bits_left(PutBitContext* s) +{ + return (s->buf_end - s->buf_ptr) * 8 - 32 + s->bit_left; +} + /** * Pad the end of the output stream with zeros. */ From 4ff5167ee7fdee6d35c1bb2558172329ae6ec770 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Fri, 28 Jun 2013 04:03:47 +0200 Subject: [PATCH 17/17] wmapro: make sure there is room to store the current packet Prevent horrid and hard to trace struct overwrite. Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit e30b068ef79f604ff439418da07f7e2efd01d4ea) Signed-off-by: Reinhard Tartler --- libavcodec/wmaprodec.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libavcodec/wmaprodec.c b/libavcodec/wmaprodec.c index 1b7797c9f2..cc8df9b900 100644 --- a/libavcodec/wmaprodec.c +++ b/libavcodec/wmaprodec.c @@ -1466,6 +1466,14 @@ static void save_bits(WMAProDecodeCtx *s, GetBitContext* gb, int len, return; } + if (len > put_bits_left(&s->pb)) { + av_log(s->avctx, AV_LOG_ERROR, + "Cannot append %d bits, only %d bits available.\n", + len, put_bits_left(&s->pb)); + s->packet_loss = 1; + return; + } + s->num_saved_bits += len; if (!append) { avpriv_copy_bits(&s->pb, gb->buffer + (get_bits_count(gb) >> 3),