From 819541ff833d8e31aa1423ccf18005584451ba59 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Fri, 15 Nov 2013 10:23:04 +0100 Subject: [PATCH 1/5] gifdec: convert to bytestream2 (cherry picked from commit 1f3e56b6dcc163a705704e98569d4850a31d651c) Signed-off-by: Reinhard Tartler --- libavcodec/gifdec.c | 67 ++++++++++++++++++++++----------------------- libavcodec/lzw.c | 7 +++-- libavcodec/lzw.h | 2 +- 3 files changed, 38 insertions(+), 38 deletions(-) diff --git a/libavcodec/gifdec.c b/libavcodec/gifdec.c index 8636780375..99c24d50ab 100644 --- a/libavcodec/gifdec.c +++ b/libavcodec/gifdec.c @@ -49,8 +49,7 @@ typedef struct GifState { int gce_delay; /* LZW compatible decoder */ - const uint8_t *bytestream; - const uint8_t *bytestream_end; + GetByteContext gb; LZWState *lzw; /* aux buffers */ @@ -69,11 +68,11 @@ static int gif_read_image(GifState *s) int is_interleaved, has_local_palette, y, pass, y1, linesize, n, i; uint8_t *ptr, *spal, *palette, *ptr1; - left = bytestream_get_le16(&s->bytestream); - top = bytestream_get_le16(&s->bytestream); - width = bytestream_get_le16(&s->bytestream); - height = bytestream_get_le16(&s->bytestream); - flags = bytestream_get_byte(&s->bytestream); + left = bytestream2_get_le16(&s->gb); + top = bytestream2_get_le16(&s->gb); + width = bytestream2_get_le16(&s->gb); + height = bytestream2_get_le16(&s->gb); + flags = bytestream2_get_byte(&s->gb); is_interleaved = flags & 0x40; has_local_palette = flags & 0x80; bits_per_pixel = (flags & 0x07) + 1; @@ -81,7 +80,7 @@ static int gif_read_image(GifState *s) av_dlog(s->avctx, "gif: image x=%d y=%d w=%d h=%d\n", left, top, width, height); if (has_local_palette) { - bytestream_get_buffer(&s->bytestream, s->local_palette, 3 * (1 << bits_per_pixel)); + bytestream2_get_buffer(&s->gb, s->local_palette, 3 * (1 << bits_per_pixel)); palette = s->local_palette; } else { palette = s->global_palette; @@ -110,9 +109,9 @@ static int gif_read_image(GifState *s) s->image_palette[s->transparent_color_index] = 0; /* now get the image data */ - code_size = bytestream_get_byte(&s->bytestream); - ff_lzw_decode_init(s->lzw, code_size, s->bytestream, - s->bytestream_end - s->bytestream, FF_LZW_GIF); + code_size = bytestream2_get_byte(&s->gb); + ff_lzw_decode_init(s->lzw, code_size, s->gb.buffer, + bytestream2_get_bytes_left(&s->gb), FF_LZW_GIF); /* read all the image */ linesize = s->picture.linesize[0]; @@ -155,7 +154,8 @@ static int gif_read_image(GifState *s) } /* read the garbage data until end marker is found */ ff_lzw_decode_tail(s->lzw); - s->bytestream = ff_lzw_cur_ptr(s->lzw); + + bytestream2_skip(&s->gb, ff_lzw_size_read(s->lzw)); return 0; } @@ -164,8 +164,8 @@ static int gif_read_extension(GifState *s) int ext_code, ext_len, i, gce_flags, gce_transparent_index; /* extension */ - ext_code = bytestream_get_byte(&s->bytestream); - ext_len = bytestream_get_byte(&s->bytestream); + ext_code = bytestream2_get_byte(&s->gb); + ext_len = bytestream2_get_byte(&s->gb); av_dlog(s->avctx, "gif: ext_code=0x%x len=%d\n", ext_code, ext_len); @@ -174,9 +174,9 @@ static int gif_read_extension(GifState *s) if (ext_len != 4) goto discard_ext; s->transparent_color_index = -1; - gce_flags = bytestream_get_byte(&s->bytestream); - s->gce_delay = bytestream_get_le16(&s->bytestream); - gce_transparent_index = bytestream_get_byte(&s->bytestream); + gce_flags = bytestream2_get_byte(&s->gb); + s->gce_delay = bytestream2_get_le16(&s->gb); + gce_transparent_index = bytestream2_get_byte(&s->gb); if (gce_flags & 0x01) s->transparent_color_index = gce_transparent_index; else @@ -187,7 +187,7 @@ static int gif_read_extension(GifState *s) gce_flags, s->gce_delay, s->transparent_color_index, s->gce_disposal); - ext_len = bytestream_get_byte(&s->bytestream); + ext_len = bytestream2_get_byte(&s->gb); break; } @@ -195,8 +195,8 @@ static int gif_read_extension(GifState *s) discard_ext: while (ext_len != 0) { for (i = 0; i < ext_len; i++) - bytestream_get_byte(&s->bytestream); - ext_len = bytestream_get_byte(&s->bytestream); + bytestream2_get_byte(&s->gb); + ext_len = bytestream2_get_byte(&s->gb); av_dlog(s->avctx, "gif: ext_len1=%d\n", ext_len); } @@ -209,31 +209,31 @@ static int gif_read_header1(GifState *s) int v, n; int has_global_palette; - if (s->bytestream_end < s->bytestream + 13) + if (bytestream2_get_bytes_left(&s->gb) < 13) return AVERROR_INVALIDDATA; /* read gif signature */ - bytestream_get_buffer(&s->bytestream, sig, 6); + bytestream2_get_buffer(&s->gb, sig, 6); if (memcmp(sig, gif87a_sig, 6) != 0 && memcmp(sig, gif89a_sig, 6) != 0) return AVERROR_INVALIDDATA; /* read screen header */ s->transparent_color_index = -1; - s->screen_width = bytestream_get_le16(&s->bytestream); - s->screen_height = bytestream_get_le16(&s->bytestream); + s->screen_width = bytestream2_get_le16(&s->gb); + s->screen_height = bytestream2_get_le16(&s->gb); if( (unsigned)s->screen_width > 32767 || (unsigned)s->screen_height > 32767){ av_log(NULL, AV_LOG_ERROR, "picture size too large\n"); return AVERROR_INVALIDDATA; } - v = bytestream_get_byte(&s->bytestream); + v = bytestream2_get_byte(&s->gb); s->color_resolution = ((v & 0x70) >> 4) + 1; has_global_palette = (v & 0x80); s->bits_per_pixel = (v & 0x07) + 1; - s->background_color_index = bytestream_get_byte(&s->bytestream); - bytestream_get_byte(&s->bytestream); /* ignored */ + s->background_color_index = bytestream2_get_byte(&s->gb); + bytestream2_get_byte(&s->gb); /* ignored */ av_dlog(s->avctx, "gif: screen_w=%d screen_h=%d bpp=%d global_palette=%d\n", s->screen_width, s->screen_height, s->bits_per_pixel, @@ -241,17 +241,17 @@ static int gif_read_header1(GifState *s) if (has_global_palette) { n = 1 << s->bits_per_pixel; - if (s->bytestream_end < s->bytestream + n * 3) + if (bytestream2_get_bytes_left(&s->gb) < n * 3) return AVERROR_INVALIDDATA; - bytestream_get_buffer(&s->bytestream, s->global_palette, n * 3); + bytestream2_get_buffer(&s->gb, s->global_palette, n * 3); } return 0; } static int gif_parse_next_image(GifState *s) { - while (s->bytestream < s->bytestream_end) { - int code = bytestream_get_byte(&s->bytestream); + while (bytestream2_get_bytes_left(&s->gb) > 0) { + int code = bytestream2_get_byte(&s->gb); int ret; av_dlog(s->avctx, "gif: code=%02x '%c'\n", code, code); @@ -295,8 +295,7 @@ static int gif_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVFrame *picture = data; int ret; - s->bytestream = buf; - s->bytestream_end = buf + buf_size; + bytestream2_init(&s->gb, buf, buf_size); if ((ret = gif_read_header1(s)) < 0) return ret; @@ -318,7 +317,7 @@ static int gif_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, *picture = s->picture; *got_frame = 1; - return s->bytestream - buf; + return bytestream2_tell(&s->gb); } static av_cold int gif_decode_close(AVCodecContext *avctx) diff --git a/libavcodec/lzw.c b/libavcodec/lzw.c index 2c99014c2a..016714021c 100644 --- a/libavcodec/lzw.c +++ b/libavcodec/lzw.c @@ -43,7 +43,7 @@ static const uint16_t mask[17] = }; struct LZWState { - const uint8_t *pbuf, *ebuf; + const uint8_t *buf_start, *pbuf, *ebuf; int bbits; unsigned int bbuf; @@ -92,9 +92,10 @@ static int lzw_get_code(struct LZWState * s) return c & s->curmask; } -const uint8_t* ff_lzw_cur_ptr(LZWState *p) +int ff_lzw_size_read(LZWState *p) { - return ((struct LZWState*)p)->pbuf; + struct LZWState *s = p; + return s->pbuf - s->buf_start; } void ff_lzw_decode_tail(LZWState *p) diff --git a/libavcodec/lzw.h b/libavcodec/lzw.h index ab782f5219..d925d35e27 100644 --- a/libavcodec/lzw.h +++ b/libavcodec/lzw.h @@ -47,7 +47,7 @@ void ff_lzw_decode_open(LZWState **p); void ff_lzw_decode_close(LZWState **p); int ff_lzw_decode_init(LZWState *s, int csize, const uint8_t *buf, int buf_size, int mode); int ff_lzw_decode(LZWState *s, uint8_t *buf, int len); -const uint8_t* ff_lzw_cur_ptr(LZWState *lzw); +int ff_lzw_size_read(LZWState *lzw); void ff_lzw_decode_tail(LZWState *lzw); /** LZW encode state */ From ffa83bcc49375a7760ff9cbc889ce7171e8afe4a Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 28 Nov 2013 10:54:35 +0100 Subject: [PATCH 2/5] lzw: switch to bytestream2 Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC:libav-stable@libav.org (cherry picked from commit e89aa4bf56e5b5c45f569eb12733519789e057da) Signed-off-by: Reinhard Tartler --- libavcodec/lzw.c | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/libavcodec/lzw.c b/libavcodec/lzw.c index 016714021c..fae5687ab7 100644 --- a/libavcodec/lzw.c +++ b/libavcodec/lzw.c @@ -28,6 +28,7 @@ */ #include "avcodec.h" +#include "bytestream.h" #include "lzw.h" #include "libavutil/mem.h" @@ -43,7 +44,7 @@ static const uint16_t mask[17] = }; struct LZWState { - const uint8_t *buf_start, *pbuf, *ebuf; + GetByteContext gb; int bbits; unsigned int bbuf; @@ -73,9 +74,9 @@ static int lzw_get_code(struct LZWState * s) if(s->mode == FF_LZW_GIF) { while (s->bbits < s->cursize) { if (!s->bs) { - s->bs = *s->pbuf++; + s->bs = bytestream2_get_byte(&s->gb); } - s->bbuf |= (*s->pbuf++) << s->bbits; + s->bbuf |= bytestream2_get_byte(&s->gb) << s->bbits; s->bbits += 8; s->bs--; } @@ -83,7 +84,7 @@ static int lzw_get_code(struct LZWState * s) s->bbuf >>= s->cursize; } else { // TIFF while (s->bbits < s->cursize) { - s->bbuf = (s->bbuf << 8) | (*s->pbuf++); + s->bbuf = (s->bbuf << 8) | bytestream2_get_byte(&s->gb); s->bbits += 8; } c = s->bbuf >> (s->bbits - s->cursize); @@ -95,7 +96,7 @@ static int lzw_get_code(struct LZWState * s) int ff_lzw_size_read(LZWState *p) { struct LZWState *s = p; - return s->pbuf - s->buf_start; + return bytestream2_tell(&s->gb); } void ff_lzw_decode_tail(LZWState *p) @@ -103,17 +104,12 @@ void ff_lzw_decode_tail(LZWState *p) struct LZWState *s = (struct LZWState *)p; if(s->mode == FF_LZW_GIF) { - while (s->bs > 0) { - if (s->bs >= s->ebuf - s->pbuf) { - s->pbuf = s->ebuf; - break; - } else { - s->pbuf += s->bs; - s->bs = *s->pbuf++; - } + while (s->bs > 0 && bytestream2_get_bytes_left(&s->gb)) { + bytestream2_skip(&s->gb, s->bs); + s->bs = bytestream2_get_byte(&s->gb); } }else - s->pbuf= s->ebuf; + bytestream2_skip(&s->gb, bytestream2_get_bytes_left(&s->gb)); } av_cold void ff_lzw_decode_open(LZWState **p) @@ -141,8 +137,7 @@ int ff_lzw_decode_init(LZWState *p, int csize, const uint8_t *buf, int buf_size, if(csize < 1 || csize >= LZW_MAXBITS) return -1; /* read buffer */ - s->pbuf = buf; - s->ebuf = s->pbuf + buf_size; + bytestream2_init(&s->gb, buf, buf_size); s->bbuf = 0; s->bbits = 0; s->bs = 0; From a8f6d93071a8ac1f039a4ee2ae1f74dcd77da1cb Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 28 Nov 2013 10:54:35 +0100 Subject: [PATCH 3/5] pmpdec: check that there is at least one audio packet. The code cannot handle there being none, but that should not happen for valid files. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC:libav-stable@libav.org (cherry picked from commit 1b5d065ca722eb8028c7a08e054b6da3419faf5d) Signed-off-by: Reinhard Tartler --- libavformat/pmpdec.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libavformat/pmpdec.c b/libavformat/pmpdec.c index 6cdce107c4..b2c613ad97 100644 --- a/libavformat/pmpdec.c +++ b/libavformat/pmpdec.c @@ -124,6 +124,11 @@ static int pmp_packet(AVFormatContext *s, AVPacket *pkt) if (pmp->cur_stream == 0) { int num_packets; pmp->audio_packets = avio_r8(pb); + if (!pmp->audio_packets) { + av_log(s, AV_LOG_ERROR, "No audio packets.\n"); + return AVERROR_INVALIDDATA; + } + num_packets = (pmp->num_streams - 1) * pmp->audio_packets + 1; avio_skip(pb, 8); pmp->current_packet = 0; From 24a8dfd37b45d63e5f6332cfd12b58ad482f3df2 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 27 Oct 2013 15:00:36 -0400 Subject: [PATCH 4/5] lavr: check that current_buffer is not NULL before using it Fixes a segfault during resampling when compiled with -DDEBUG. Fixes all fate-lavr-resample tests with -DDEBUG. CC:libav-stable@libav.org (cherry picked from commit 211ca69b13eb0a127a9ef7e70ddaccdab125d1c5) Signed-off-by: Reinhard Tartler --- libavresample/utils.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavresample/utils.c b/libavresample/utils.c index ed7f470483..36d9d04430 100644 --- a/libavresample/utils.c +++ b/libavresample/utils.c @@ -350,7 +350,8 @@ int attribute_align_arg avresample_convert(AVAudioResampleContext *avr, resample_out = &output_buffer; else resample_out = avr->resample_out_buffer; - av_dlog(avr, "[resample] %s to %s\n", current_buffer->name, + av_dlog(avr, "[resample] %s to %s\n", + current_buffer ? current_buffer->name : "null", resample_out->name); ret = ff_audio_resample(avr->resample, resample_out, current_buffer); From 0e8ae6d10c609bb968c141aa2436413a55852590 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Tue, 22 Oct 2013 19:17:10 +0200 Subject: [PATCH 5/5] mpegvideo: Drop a faulty assert That check is easily reachable by faulty input. CC:libav-stable@libav.org Reported-by: Torsten Sadowski (cherry picked from commit 72072bf9de3241848ea86f68d2297b7a5d6ad49b) Signed-off-by: Reinhard Tartler --- libavcodec/mpegvideo.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c index 2f65779f2a..eb71670379 100644 --- a/libavcodec/mpegvideo.c +++ b/libavcodec/mpegvideo.c @@ -1521,8 +1521,12 @@ int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx) s->last_picture_ptr->owner2 = s; } - assert(s->pict_type == AV_PICTURE_TYPE_I || (s->last_picture_ptr && - s->last_picture_ptr->f.data[0])); + if (s->pict_type != AV_PICTURE_TYPE_I && + !(s->last_picture_ptr && s->last_picture_ptr->f.data[0])) { + av_log(s, AV_LOG_ERROR, + "Non-reference picture received and no reference available\n"); + return AVERROR_INVALIDDATA; + } if (s->picture_structure!= PICT_FRAME && s->out_format != FMT_H264) { int i;