--- Begin Message ---
Package: release.debian.org
Severity: normal
User: [email protected]
Usertags: unblock
Please unblock package vlc version 2.2.4-14. It updates the embedded copy of
ffmpeg 2.8 to the latest upstream bug fix release.
Since debdiff does not cope very well with multi-component upstream tarballs,
there are two diffs attached. vlc.diff contains the changes to debian/ and
ffmpeg.diff contains the changes between ffmpeg 2.8.10 and 2.8.11.
The changelog for ffmpeg 2.8.11 is below. The release fixes CVE-2016-9561,
CVE-2017-5024 and CVE-2017-5025.
version 2.8.11
- avcodec/h264_slice: Clear ref_counts on redundant slices
- lavf/mov.c: Avoid heap allocation wrap in mov_read_uuid
- lavf/mov.c: Avoid heap allocation wrap in mov_read_hdlr
- avcodec/pictordec: Fix logic error
- avcodec/movtextdec: Fix decode_styl() cleanup
- lavf/matroskadec: fix is_keyframe for early Blocks
- configure: bump year
- avcodec/pngdec: Check trns more completely
- avcodec/interplayvideo: Move parameter change check up
- avcodec/mjpegdec: Check for for the bitstream end in
mjpeg_decode_scan_progressive_ac()
- avformat/flacdec: Check avio_read result when reading flac block header.
- avcodec/utils: correct align value for interplay
- avcodec/vp56: Check for the bitstream end, pass error codes on
- avcodec/mjpegdec: Check remaining bitstream in ljpeg_decode_yuv_scan()
- avcodec/pngdec: Fix off by 1 size in decode_zbuf()
- avformat/avidec: skip odml master index chunks in avi_sync
- avcodec/mjpegdec: Check for rgb before flipping
- avutil/random_seed: Reduce the time needed on systems with very low precision
clock()
- avutil/random_seed: Improve get_generic_seed() with higher precision clock()
- avformat/utils: Print verbose error message if stream count exceeds
max_streams
- avformat/options_table: Set the default maximum number of streams to 1000
- avutil: Add av_image_check_size2()
- avformat: Add max_streams option
- avcodec/ffv1enc: Allocate smaller packet if the worst case size cannot be
allocated
- avcodec/mpeg4videodec: Fix undefined shifts in
mpeg4_decode_sprite_trajectory()
- avformat/oggdec: Skip streams in duration correction that did not had their
duration set.
- avcodec/ffv1enc: Fix size of first slice
- pgssubdec: reset rle_data_len/rle_remaining_len on allocation error
unblock vlc/2.2.4-14
Cheers
--
Sebastian Ramacher
diff --git a/debian/changelog b/debian/changelog
index 781f9848c9..739c269c42 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+vlc (2.2.4-14) unstable; urgency=medium
+
+ [ Mateusz Ĺukasik ]
+ * Update to ffmpeg 2.8.11.
+
+ -- Sebastian Ramacher <[email protected]> Tue, 14 Feb 2017 20:17:50 +0100
+
vlc (2.2.4-13) unstable; urgency=medium
* debian/control: Switch to libopenmpt's libmodplug comat layer.
diff --git a/debian/rules b/debian/rules
index 35ebba4e17..8d48ec81b8 100755
--- a/debian/rules
+++ b/debian/rules
@@ -346,7 +346,7 @@ override_dh_autoreconf:
override_dh_auto_configure:
mkdir -p $(ffmpegbuild) $(ffmpegprefix)
cd $(ffmpegbuild) && \
- $(CURDIR)/ffmpeg-2-8-10/configure $(ffmpegflags)
+ $(CURDIR)/ffmpeg-2-8-11/configure $(ffmpegflags)
dh_auto_build --sourcedirectory $(ffmpegbuild) -- V=1
$(MAKE) -C $(ffmpegbuild) install-libs install-headers V=1
PKG_CONFIG_PATH=$(ffmpegprefix)/lib/pkgconfig \
diff --git a/debian/watch b/debian/watch
index 764a7c1834..8c442743e7 100644
--- a/debian/watch
+++ b/debian/watch
@@ -1,5 +1,5 @@
version=4
opts=pgpsigurlmangle=s/$/.asc/ \
http://download.videolan.org/pub/videolan/vlc/([\d][\d\.]+[a-z]?)/vlc-([\d][\d\.]+[a-z]?)\.tar\.xz
debian
-opts=component=ffmpeg-2-8-10 \
-https://ffmpeg.org/releases/ffmpeg-2\.8\.([0-9.]+)\.tar\.xz 2.8.10
+opts=component=ffmpeg-2-8-11 \
+https://ffmpeg.org/releases/ffmpeg-2\.8\.([0-9.]+)\.tar\.xz 2.8.11
diff --git a/Changelog b/Changelog
index ac863b2260..83004c4fd9 100644
--- a/Changelog
+++ b/Changelog
@@ -1,6 +1,36 @@
Entries are sorted chronologically from oldest to youngest within each release,
releases are sorted from youngest to oldest.
+version 2.8.11
+- avcodec/h264_slice: Clear ref_counts on redundant slices
+- lavf/mov.c: Avoid heap allocation wrap in mov_read_uuid
+- lavf/mov.c: Avoid heap allocation wrap in mov_read_hdlr
+- avcodec/pictordec: Fix logic error
+- avcodec/movtextdec: Fix decode_styl() cleanup
+- lavf/matroskadec: fix is_keyframe for early Blocks
+- configure: bump year
+- avcodec/pngdec: Check trns more completely
+- avcodec/interplayvideo: Move parameter change check up
+- avcodec/mjpegdec: Check for for the bitstream end in mjpeg_decode_scan_progressive_ac()
+- avformat/flacdec: Check avio_read result when reading flac block header.
+- avcodec/utils: correct align value for interplay
+- avcodec/vp56: Check for the bitstream end, pass error codes on
+- avcodec/mjpegdec: Check remaining bitstream in ljpeg_decode_yuv_scan()
+- avcodec/pngdec: Fix off by 1 size in decode_zbuf()
+- avformat/avidec: skip odml master index chunks in avi_sync
+- avcodec/mjpegdec: Check for rgb before flipping
+- avutil/random_seed: Reduce the time needed on systems with very low precision clock()
+- avutil/random_seed: Improve get_generic_seed() with higher precision clock()
+- avformat/utils: Print verbose error message if stream count exceeds max_streams
+- avformat/options_table: Set the default maximum number of streams to 1000
+- avutil: Add av_image_check_size2()
+- avformat: Add max_streams option
+- avcodec/ffv1enc: Allocate smaller packet if the worst case size cannot be allocated
+- avcodec/mpeg4videodec: Fix undefined shifts in mpeg4_decode_sprite_trajectory()
+- avformat/oggdec: Skip streams in duration correction that did not had their duration set.
+- avcodec/ffv1enc: Fix size of first slice
+- pgssubdec: reset rle_data_len/rle_remaining_len on allocation error
+
version 2.8.10
- avformat/http: Match chunksize checks to master..3.0
- Changelog: fix typos
diff --git a/RELEASE b/RELEASE
index 4067d1db71..38bc52136e 100644
--- a/RELEASE
+++ b/RELEASE
@@ -1 +1 @@
-2.8.10
+2.8.11
diff --git a/configure b/configure
index 684d5c1918..180f3ef0ef 100755
--- a/configure
+++ b/configure
@@ -6144,7 +6144,7 @@ cat > $TMPH <<EOF
#define FFMPEG_CONFIG_H
#define FFMPEG_CONFIGURATION "$(c_escape $FFMPEG_CONFIGURATION)"
#define FFMPEG_LICENSE "$(c_escape $license)"
-#define CONFIG_THIS_YEAR 2016
+#define CONFIG_THIS_YEAR 2017
#define FFMPEG_DATADIR "$(eval c_escape $datadir)"
#define AVCONV_DATADIR "$(eval c_escape $datadir)"
#define CC_IDENT "$(c_escape ${cc_ident:-Unknown compiler})"
diff --git a/doc/Doxyfile b/doc/Doxyfile
index 74fca4017f..7776739ca7 100644
--- a/doc/Doxyfile
+++ b/doc/Doxyfile
@@ -31,7 +31,7 @@ PROJECT_NAME = FFmpeg
# This could be handy for archiving the generated documentation or
# if some version control system is used.
-PROJECT_NUMBER = 2.8.10
+PROJECT_NUMBER = 2.8.11
# With the PROJECT_LOGO tag one can specify a logo or icon that is included
# in the documentation. The maximum height of the logo should not exceed 55
diff --git a/doc/formats.texi b/doc/formats.texi
index 617cda54a9..b62ca43dd7 100644
--- a/doc/formats.texi
+++ b/doc/formats.texi
@@ -205,6 +205,10 @@ For example to separate the fields with newlines and indention:
ffprobe -dump_separator "
" -i ~/videos/matrixbench_mpeg2.mpg
@end example
+
+@item max_streams @var{integer} (@emph{input})
+Specifies the maximum number of streams. This can be used to reject files that
+would require too many resources due to a large number of streams.
@end table
@c man end FORMAT OPTIONS
diff --git a/libavcodec/ffv1enc.c b/libavcodec/ffv1enc.c
index 00ef800c30..3b425d68ed 100644
--- a/libavcodec/ffv1enc.c
+++ b/libavcodec/ffv1enc.c
@@ -1192,7 +1192,6 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
FFV1Context *f = avctx->priv_data;
RangeCoder *const c = &f->slice_context[0]->c;
AVFrame *const p = f->picture.f;
- int used_count = 0;
uint8_t keystate = 128;
uint8_t *buf_p;
int i, ret;
@@ -1248,6 +1247,11 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
if (f->version > 3)
maxsize = AV_INPUT_BUFFER_MIN_SIZE + avctx->width*avctx->height*3LL*4;
+ if (maxsize > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE - 32) {
+ av_log(avctx, AV_LOG_WARNING, "Cannot allocate worst case packet size, the encoding could fail\n");
+ maxsize = INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE - 32;
+ }
+
if ((ret = ff_alloc_packet2(avctx, pkt, maxsize, 0)) < 0)
return ret;
@@ -1277,11 +1281,17 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
}
}
- for (i = 1; i < f->slice_count; i++) {
+ for (i = 0; i < f->slice_count; i++) {
FFV1Context *fs = f->slice_context[i];
- uint8_t *start = pkt->data + (pkt->size - used_count) * (int64_t)i / f->slice_count;
+ uint8_t *start = pkt->data + pkt->size * (int64_t)i / f->slice_count;
int len = pkt->size / f->slice_count;
- ff_init_range_encoder(&fs->c, start, len);
+ if (i) {
+ ff_init_range_encoder(&fs->c, start, len);
+ } else {
+ av_assert0(fs->c.bytestream_end >= fs->c.bytestream_start + len);
+ av_assert0(fs->c.bytestream < fs->c.bytestream_start + len);
+ fs->c.bytestream_end = fs->c.bytestream_start + len;
+ }
}
avctx->execute(avctx, encode_slice, &f->slice_context[0], NULL,
f->slice_count, sizeof(void *));
diff --git a/libavcodec/h264.c b/libavcodec/h264.c
index fead5ae116..4fc2aed302 100644
--- a/libavcodec/h264.c
+++ b/libavcodec/h264.c
@@ -1587,7 +1587,9 @@ again:
#endif
} else
context_count++;
- }
+ } else
+ sl->ref_count[0] = sl->ref_count[1] = 0;
+ break;
break;
case NAL_DPA:
case NAL_DPB:
diff --git a/libavcodec/interplayvideo.c b/libavcodec/interplayvideo.c
index 3c3212e1fe..48dc3783b4 100644
--- a/libavcodec/interplayvideo.c
+++ b/libavcodec/interplayvideo.c
@@ -988,6 +988,11 @@ static int ipvideo_decode_frame(AVCodecContext *avctx,
AVFrame *frame = data;
int ret;
+ if (av_packet_get_side_data(avpkt, AV_PKT_DATA_PARAM_CHANGE, NULL)) {
+ av_frame_unref(s->last_frame);
+ av_frame_unref(s->second_last_frame);
+ }
+
if (buf_size < 2)
return AVERROR_INVALIDDATA;
@@ -999,10 +1004,6 @@ static int ipvideo_decode_frame(AVCodecContext *avctx,
if (buf_size < s->decoding_map_size + 2)
return buf_size;
- if (av_packet_get_side_data(avpkt, AV_PKT_DATA_PARAM_CHANGE, NULL)) {
- av_frame_unref(s->last_frame);
- av_frame_unref(s->second_last_frame);
- }
s->decoding_map = buf + 2;
bytestream2_init(&s->stream_ptr, buf + 2 + s->decoding_map_size,
diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c
index adc2597dba..d9d18e2c82 100644
--- a/libavcodec/mjpegdec.c
+++ b/libavcodec/mjpegdec.c
@@ -1076,6 +1076,10 @@ static int ljpeg_decode_yuv_scan(MJpegDecodeContext *s, int predictor,
for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
+ if (get_bits_left(&s->gb) < 1) {
+ av_log(s->avctx, AV_LOG_ERROR, "bitstream end in yuv_scan\n");
+ return AVERROR_INVALIDDATA;
+ }
if (s->restart_interval && !s->restart_count){
s->restart_count = s->restart_interval;
resync_mb_x = mb_x;
@@ -1387,6 +1391,10 @@ static int mjpeg_decode_scan_progressive_ac(MJpegDecodeContext *s, int ss,
int block_idx = mb_y * s->block_stride[c];
int16_t (*block)[64] = &s->blocks[c][block_idx];
uint8_t *last_nnz = &s->last_nnz[c][block_idx];
+ if (get_bits_left(&s->gb) <= 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "bitstream truncated in mjpeg_decode_scan_progressive_ac\n");
+ return AVERROR_INVALIDDATA;
+ }
for (mb_x = 0; mb_x < s->mb_width; mb_x++, block++, last_nnz++) {
int ret;
if (s->restart_interval && !s->restart_count)
@@ -2308,7 +2316,7 @@ the_end:
}
}
}
- if (s->flipped) {
+ if (s->flipped && !s->rgb) {
int j;
avcodec_get_chroma_sub_sample(s->avctx->pix_fmt, &hshift, &vshift);
for (index=0; index<4; index++) {
diff --git a/libavcodec/movtextdec.c b/libavcodec/movtextdec.c
index cbaa6b2974..2f3ef7d02e 100644
--- a/libavcodec/movtextdec.c
+++ b/libavcodec/movtextdec.c
@@ -115,6 +115,8 @@ static void mov_text_cleanup(MovTextContext *m)
av_freep(&m->s[i]);
}
av_freep(&m->s);
+ m->count_s = 0;
+ m->style_entries = 0;
}
}
@@ -278,12 +280,14 @@ static int decode_hclr(const uint8_t *tsmb, MovTextContext *m, AVPacket *avpkt)
static int decode_styl(const uint8_t *tsmb, MovTextContext *m, AVPacket *avpkt)
{
int i;
- m->style_entries = AV_RB16(tsmb);
+ int style_entries = AV_RB16(tsmb);
tsmb += 2;
// A single style record is of length 12 bytes.
- if (m->tracksize + m->size_var + 2 + m->style_entries * 12 > avpkt->size)
+ if (m->tracksize + m->size_var + 2 + style_entries * 12 > avpkt->size)
return -1;
+ m->style_entries = style_entries;
+
m->box_flags |= STYL_BOX;
for(i = 0; i < m->style_entries; i++) {
m->s_temp = av_malloc(sizeof(*m->s_temp));
diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c
index 2c34d21a14..8d015efced 100644
--- a/libavcodec/mpeg4videodec.c
+++ b/libavcodec/mpeg4videodec.c
@@ -314,13 +314,13 @@ static int mpeg4_decode_sprite_trajectory(Mpeg4DecContext *ctx, GetBitContext *g
min_ab = FFMIN(alpha, beta);
w3 = w2 >> min_ab;
h3 = h2 >> min_ab;
- s->sprite_offset[0][0] = (sprite_ref[0][0] << (alpha + beta + rho - min_ab)) +
+ s->sprite_offset[0][0] = (sprite_ref[0][0] * (1<<(alpha + beta + rho - min_ab))) +
(-r * sprite_ref[0][0] + virtual_ref[0][0]) *
h3 * (-vop_ref[0][0]) +
(-r * sprite_ref[0][0] + virtual_ref[1][0]) *
w3 * (-vop_ref[0][1]) +
(1 << (alpha + beta + rho - min_ab - 1));
- s->sprite_offset[0][1] = (sprite_ref[0][1] << (alpha + beta + rho - min_ab)) +
+ s->sprite_offset[0][1] = (sprite_ref[0][1] * (1 << (alpha + beta + rho - min_ab))) +
(-r * sprite_ref[0][1] + virtual_ref[0][1]) *
h3 * (-vop_ref[0][0]) +
(-r * sprite_ref[0][1] + virtual_ref[1][1]) *
@@ -367,10 +367,10 @@ static int mpeg4_decode_sprite_trajectory(Mpeg4DecContext *ctx, GetBitContext *g
int shift_y = 16 - ctx->sprite_shift[0];
int shift_c = 16 - ctx->sprite_shift[1];
for (i = 0; i < 2; i++) {
- s->sprite_offset[0][i] <<= shift_y;
- s->sprite_offset[1][i] <<= shift_c;
- s->sprite_delta[0][i] <<= shift_y;
- s->sprite_delta[1][i] <<= shift_y;
+ s->sprite_offset[0][i] *= 1 << shift_y;
+ s->sprite_offset[1][i] *= 1 << shift_c;
+ s->sprite_delta[0][i] *= 1 << shift_y;
+ s->sprite_delta[1][i] *= 1 << shift_y;
ctx->sprite_shift[i] = 16;
}
s->real_sprite_warping_points = ctx->num_sprite_warping_points;
diff --git a/libavcodec/pgssubdec.c b/libavcodec/pgssubdec.c
index 6ff6cc4059..b549ff2bf4 100644
--- a/libavcodec/pgssubdec.c
+++ b/libavcodec/pgssubdec.c
@@ -300,8 +300,11 @@ static int parse_object_segment(AVCodecContext *avctx,
av_fast_padded_malloc(&object->rle, &object->rle_buffer_size, rle_bitmap_len);
- if (!object->rle)
+ if (!object->rle) {
+ object->rle_data_len = 0;
+ object->rle_remaining_len = 0;
return AVERROR(ENOMEM);
+ }
memcpy(object->rle, buf, buf_size);
object->rle_data_len = buf_size;
diff --git a/libavcodec/pictordec.c b/libavcodec/pictordec.c
index ff6eb7f4fc..0cfc785832 100644
--- a/libavcodec/pictordec.c
+++ b/libavcodec/pictordec.c
@@ -142,7 +142,7 @@ static int decode_frame(AVCodecContext *avctx,
if (av_image_check_size(s->width, s->height, 0, avctx) < 0)
return -1;
- if (s->width != avctx->width && s->height != avctx->height) {
+ if (s->width != avctx->width || s->height != avctx->height) {
ret = ff_set_dimensions(avctx, s->width, s->height);
if (ret < 0)
return ret;
diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c
index b4d1fb59ae..61c4ac8e0a 100644
--- a/libavcodec/pngdec.c
+++ b/libavcodec/pngdec.c
@@ -435,13 +435,13 @@ static int decode_zbuf(AVBPrint *bp, const uint8_t *data,
av_bprint_init(bp, 0, -1);
while (zstream.avail_in > 0) {
- av_bprint_get_buffer(bp, 1, &buf, &buf_size);
- if (!buf_size) {
+ av_bprint_get_buffer(bp, 2, &buf, &buf_size);
+ if (buf_size < 2) {
ret = AVERROR(ENOMEM);
goto fail;
}
zstream.next_out = buf;
- zstream.avail_out = buf_size;
+ zstream.avail_out = buf_size - 1;
ret = inflate(&zstream, Z_PARTIAL_FLUSH);
if (ret != Z_OK && ret != Z_STREAM_END) {
ret = AVERROR_EXTERNAL;
@@ -770,6 +770,16 @@ static int decode_trns_chunk(AVCodecContext *avctx, PNGDecContext *s,
{
int v, i;
+ if (!(s->state & PNG_IHDR)) {
+ av_log(avctx, AV_LOG_ERROR, "trns before IHDR\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (s->state & PNG_IDAT) {
+ av_log(avctx, AV_LOG_ERROR, "trns after IDAT\n");
+ return AVERROR_INVALIDDATA;
+ }
+
if (s->color_type == PNG_COLOR_TYPE_PALETTE) {
if (length > 256 || !(s->state & PNG_PLTE))
return AVERROR_INVALIDDATA;
@@ -780,7 +790,8 @@ static int decode_trns_chunk(AVCodecContext *avctx, PNGDecContext *s,
}
} else if (s->color_type == PNG_COLOR_TYPE_GRAY || s->color_type == PNG_COLOR_TYPE_RGB) {
if ((s->color_type == PNG_COLOR_TYPE_GRAY && length != 2) ||
- (s->color_type == PNG_COLOR_TYPE_RGB && length != 6))
+ (s->color_type == PNG_COLOR_TYPE_RGB && length != 6) ||
+ s->bit_depth == 1)
return AVERROR_INVALIDDATA;
for (i = 0; i < length / 2; i++) {
@@ -1194,6 +1205,8 @@ exit_loop:
size_t raw_bpp = s->bpp - byte_depth;
unsigned x, y;
+ av_assert0(s->bit_depth > 1);
+
for (y = 0; y < s->height; ++y) {
uint8_t *row = &s->image_buf[s->image_linesize * y];
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index 3b85087563..6f54f530a1 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -378,6 +378,10 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height,
w_align = 4;
h_align = 4;
}
+ if (s->codec_id == AV_CODEC_ID_INTERPLAY_VIDEO) {
+ w_align = 8;
+ h_align = 8;
+ }
break;
case AV_PIX_FMT_PAL8:
case AV_PIX_FMT_BGR8:
@@ -387,7 +391,8 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height,
w_align = 4;
h_align = 4;
}
- if (s->codec_id == AV_CODEC_ID_JV) {
+ if (s->codec_id == AV_CODEC_ID_JV ||
+ s->codec_id == AV_CODEC_ID_INTERPLAY_VIDEO) {
w_align = 8;
h_align = 8;
}
diff --git a/libavcodec/vp5.c b/libavcodec/vp5.c
index 5bcf9b6217..4ec85ebde7 100644
--- a/libavcodec/vp5.c
+++ b/libavcodec/vp5.c
@@ -171,7 +171,7 @@ static int vp5_parse_coeff_models(VP56Context *s)
return 0;
}
-static void vp5_parse_coeff(VP56Context *s)
+static int vp5_parse_coeff(VP56Context *s)
{
VP56RangeCoder *c = &s->c;
VP56Model *model = s->modelp;
@@ -181,6 +181,11 @@ static void vp5_parse_coeff(VP56Context *s)
int b, i, cg, idx, ctx, ctx_last;
int pt = 0; /* plane type (0 for Y, 1 for U or V) */
+ if (c->end >= c->buffer && c->bits >= 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "End of AC stream reached in vp5_parse_coeff\n");
+ return AVERROR_INVALIDDATA;
+ }
+
for (b=0; b<6; b++) {
int ct = 1; /* code type */
@@ -246,6 +251,7 @@ static void vp5_parse_coeff(VP56Context *s)
s->coeff_ctx[ff_vp56_b6to4[b]][i] = 5;
s->above_blocks[s->above_block_idx[b]].not_null_dc = s->coeff_ctx[ff_vp56_b6to4[b]][0];
}
+ return 0;
}
static void vp5_default_models_init(VP56Context *s)
diff --git a/libavcodec/vp56.c b/libavcodec/vp56.c
index 631924828d..d8fe994b8c 100644
--- a/libavcodec/vp56.c
+++ b/libavcodec/vp56.c
@@ -381,12 +381,13 @@ static void vp56_mc(VP56Context *s, int b, int plane, uint8_t *src,
}
}
-static void vp56_decode_mb(VP56Context *s, int row, int col, int is_alpha)
+static int vp56_decode_mb(VP56Context *s, int row, int col, int is_alpha)
{
AVFrame *frame_current, *frame_ref;
VP56mb mb_type;
VP56Frame ref_frame;
int b, ab, b_max, plane, off;
+ int ret;
if (s->frames[VP56_FRAME_CURRENT]->key_frame)
mb_type = VP56_MB_INTRA;
@@ -394,14 +395,16 @@ static void vp56_decode_mb(VP56Context *s, int row, int col, int is_alpha)
mb_type = vp56_decode_mv(s, row, col);
ref_frame = ff_vp56_reference_frame[mb_type];
- s->parse_coeff(s);
+ ret = s->parse_coeff(s);
+ if (ret < 0)
+ return ret;
vp56_add_predictors_dc(s, ref_frame);
frame_current = s->frames[VP56_FRAME_CURRENT];
frame_ref = s->frames[ref_frame];
if (mb_type != VP56_MB_INTRA && !frame_ref->data[0])
- return;
+ return 0;
ab = 6*is_alpha;
b_max = 6 - 2*is_alpha;
@@ -451,6 +454,7 @@ static void vp56_decode_mb(VP56Context *s, int row, int col, int is_alpha)
s->block_coeff[4][0] = 0;
s->block_coeff[5][0] = 0;
}
+ return 0;
}
static int vp56_size_changed(VP56Context *s)
@@ -653,7 +657,9 @@ static int ff_vp56_decode_mbs(AVCodecContext *avctx, void *data,
s->block_offset[5] = s->block_offset[4];
for (mb_col=0; mb_col<s->mb_width; mb_col++) {
- vp56_decode_mb(s, mb_row, mb_col, is_alpha);
+ int ret = vp56_decode_mb(s, mb_row, mb_col, is_alpha);
+ if (ret < 0)
+ return ret;
for (y=0; y<4; y++) {
s->above_block_idx[y] += 2;
diff --git a/libavcodec/vp56.h b/libavcodec/vp56.h
index 56c30919b7..34d48228fd 100644
--- a/libavcodec/vp56.h
+++ b/libavcodec/vp56.h
@@ -74,7 +74,7 @@ typedef void (*VP56ParseVectorAdjustment)(VP56Context *s,
typedef void (*VP56Filter)(VP56Context *s, uint8_t *dst, uint8_t *src,
int offset1, int offset2, int stride,
VP56mv mv, int mask, int select, int luma);
-typedef void (*VP56ParseCoeff)(VP56Context *s);
+typedef int (*VP56ParseCoeff)(VP56Context *s);
typedef void (*VP56DefaultModelsInit)(VP56Context *s);
typedef void (*VP56ParseVectorModels)(VP56Context *s);
typedef int (*VP56ParseCoeffModels)(VP56Context *s);
diff --git a/libavcodec/vp6.c b/libavcodec/vp6.c
index a2bb4578d5..7f0a9b7d5d 100644
--- a/libavcodec/vp6.c
+++ b/libavcodec/vp6.c
@@ -40,8 +40,8 @@
#define VP6_MAX_HUFF_SIZE 12
-static void vp6_parse_coeff(VP56Context *s);
-static void vp6_parse_coeff_huffman(VP56Context *s);
+static int vp6_parse_coeff(VP56Context *s);
+static int vp6_parse_coeff_huffman(VP56Context *s);
static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size)
{
@@ -380,7 +380,7 @@ static unsigned vp6_get_nb_null(VP56Context *s)
return val;
}
-static void vp6_parse_coeff_huffman(VP56Context *s)
+static int vp6_parse_coeff_huffman(VP56Context *s)
{
VP56Model *model = s->modelp;
uint8_t *permute = s->idct_scantable;
@@ -402,7 +402,7 @@ static void vp6_parse_coeff_huffman(VP56Context *s)
break;
} else {
if (get_bits_left(&s->gb) <= 0)
- return;
+ return AVERROR_INVALIDDATA;
coeff = get_vlc2(&s->gb, vlc_coeff->table, FF_HUFFMAN_BITS, 3);
if (coeff == 0) {
if (coeff_idx) {
@@ -437,9 +437,10 @@ static void vp6_parse_coeff_huffman(VP56Context *s)
vlc_coeff = &s->ract_vlc[pt][ct][cg];
}
}
+ return 0;
}
-static void vp6_parse_coeff(VP56Context *s)
+static int vp6_parse_coeff(VP56Context *s)
{
VP56RangeCoder *c = s->ccp;
VP56Model *model = s->modelp;
@@ -449,6 +450,11 @@ static void vp6_parse_coeff(VP56Context *s)
int b, i, cg, idx, ctx;
int pt = 0; /* plane type (0 for Y, 1 for U or V) */
+ if (c->end >= c->buffer && c->bits >= 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "End of AC stream reached in vp6_parse_coeff\n");
+ return AVERROR_INVALIDDATA;
+ }
+
for (b=0; b<6; b++) {
int ct = 1; /* code type */
int run = 1;
@@ -512,6 +518,7 @@ static void vp6_parse_coeff(VP56Context *s)
s->left_block[ff_vp56_b6to4[b]].not_null_dc =
s->above_blocks[s->above_block_idx[b]].not_null_dc = !!s->block_coeff[b][0];
}
+ return 0;
}
static int vp6_block_variance(uint8_t *src, int stride)
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index a6694765b2..ba8c615b18 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -1822,6 +1822,13 @@ typedef struct AVFormatContext {
* Demuxing: Set by user.
*/
int (*open_cb)(struct AVFormatContext *s, AVIOContext **p, const char *url, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options);
+
+ /**
+ * The maximum number of streams.
+ * - encoding: unused
+ * - decoding: set by user through AVOptions (NO direct access)
+ */
+ int max_streams;
} AVFormatContext;
int av_format_get_probe_score(const AVFormatContext *s);
diff --git a/libavformat/avidec.c b/libavformat/avidec.c
index d2904ab7d2..cbe6c85636 100644
--- a/libavformat/avidec.c
+++ b/libavformat/avidec.c
@@ -1187,7 +1187,8 @@ start_sync:
if ((d[0] == 'i' && d[1] == 'x' && n < s->nb_streams) ||
// parse JUNK
(d[0] == 'J' && d[1] == 'U' && d[2] == 'N' && d[3] == 'K') ||
- (d[0] == 'i' && d[1] == 'd' && d[2] == 'x' && d[3] == '1')) {
+ (d[0] == 'i' && d[1] == 'd' && d[2] == 'x' && d[3] == '1') ||
+ (d[0] == 'i' && d[1] == 'n' && d[2] == 'd' && d[3] == 'x')) {
avio_skip(pb, size);
goto start_sync;
}
diff --git a/libavformat/flacdec.c b/libavformat/flacdec.c
index 4c1f943581..221b3e820d 100644
--- a/libavformat/flacdec.c
+++ b/libavformat/flacdec.c
@@ -49,7 +49,8 @@ static int flac_read_header(AVFormatContext *s)
/* process metadata blocks */
while (!avio_feof(s->pb) && !metadata_last) {
- avio_read(s->pb, header, 4);
+ if (avio_read(s->pb, header, 4) != 4)
+ return AVERROR(AVERROR_INVALIDDATA);
flac_parse_block_header(header, &metadata_last, &metadata_type,
&metadata_size);
switch (metadata_type) {
diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
index a52c4f0f56..4e12c840b0 100644
--- a/libavformat/matroskadec.c
+++ b/libavformat/matroskadec.c
@@ -85,6 +85,7 @@ typedef const struct EbmlSyntax {
int list_elem_size;
int data_offset;
union {
+ int64_t i;
uint64_t u;
double f;
const char *s;
@@ -600,7 +601,7 @@ static const EbmlSyntax matroska_blockgroup[] = {
{ MATROSKA_ID_SIMPLEBLOCK, EBML_BIN, 0, offsetof(MatroskaBlock, bin) },
{ MATROSKA_ID_BLOCKDURATION, EBML_UINT, 0, offsetof(MatroskaBlock, duration) },
{ MATROSKA_ID_DISCARDPADDING, EBML_SINT, 0, offsetof(MatroskaBlock, discard_padding) },
- { MATROSKA_ID_BLOCKREFERENCE, EBML_SINT, 0, offsetof(MatroskaBlock, reference) },
+ { MATROSKA_ID_BLOCKREFERENCE, EBML_SINT, 0, offsetof(MatroskaBlock, reference), { .i = INT64_MIN } },
{ MATROSKA_ID_CODECSTATE, EBML_NONE },
{ 1, EBML_UINT, 0, offsetof(MatroskaBlock, non_simple), { .u = 1 } },
{ 0 }
@@ -971,6 +972,9 @@ static int ebml_parse_nest(MatroskaDemuxContext *matroska, EbmlSyntax *syntax,
for (i = 0; syntax[i].id; i++)
switch (syntax[i].type) {
+ case EBML_SINT:
+ *(int64_t *) ((char *) data + syntax[i].data_offset) = syntax[i].def.i;
+ break;
case EBML_UINT:
*(uint64_t *) ((char *) data + syntax[i].data_offset) = syntax[i].def.u;
break;
@@ -2983,7 +2987,7 @@ static int matroska_parse_cluster_incremental(MatroskaDemuxContext *matroska)
matroska->current_cluster_num_blocks = blocks_list->nb_elem;
i = blocks_list->nb_elem - 1;
if (blocks[i].bin.size > 0 && blocks[i].bin.data) {
- int is_keyframe = blocks[i].non_simple ? !blocks[i].reference : -1;
+ int is_keyframe = blocks[i].non_simple ? blocks[i].reference == INT64_MIN : -1;
uint8_t* additional = blocks[i].additional.size > 0 ?
blocks[i].additional.data : NULL;
if (!blocks[i].non_simple)
@@ -3021,7 +3025,7 @@ static int matroska_parse_cluster(MatroskaDemuxContext *matroska)
blocks = blocks_list->elem;
for (i = 0; i < blocks_list->nb_elem; i++)
if (blocks[i].bin.size > 0 && blocks[i].bin.data) {
- int is_keyframe = blocks[i].non_simple ? !blocks[i].reference : -1;
+ int is_keyframe = blocks[i].non_simple ? blocks[i].reference == INT64_MIN : -1;
res = matroska_parse_block(matroska, blocks[i].bin.data,
blocks[i].bin.size, blocks[i].bin.pos,
cluster.timecode, blocks[i].duration,
diff --git a/libavformat/mov.c b/libavformat/mov.c
index aa6208759b..017df0fbc0 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -635,6 +635,8 @@ static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
title_size = atom.size - 24;
if (title_size > 0) {
+ if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
+ return AVERROR_INVALIDDATA;
title_str = av_malloc(title_size + 1); /* Add null terminator */
if (!title_str)
return AVERROR(ENOMEM);
@@ -3808,7 +3810,7 @@ static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
};
- if (atom.size < sizeof(uuid) || atom.size == INT64_MAX)
+ if (atom.size < sizeof(uuid) || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
return AVERROR_INVALIDDATA;
ret = avio_read(pb, uuid, sizeof(uuid));
diff --git a/libavformat/oggdec.c b/libavformat/oggdec.c
index 856e0e633e..ffd1703a1a 100644
--- a/libavformat/oggdec.c
+++ b/libavformat/oggdec.c
@@ -642,6 +642,8 @@ static int ogg_get_length(AVFormatContext *s)
int64_t pts;
if (i < 0) continue;
pts = ogg_calc_pts(s, i, NULL);
+ if (s->streams[i]->duration == AV_NOPTS_VALUE)
+ continue;
if (pts != AV_NOPTS_VALUE && s->streams[i]->start_time == AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
s->streams[i]->duration -= pts;
ogg->streams[i].got_start= 1;
diff --git a/libavformat/options_table.h b/libavformat/options_table.h
index 8f3c3100f7..1ffce5e068 100644
--- a/libavformat/options_table.h
+++ b/libavformat/options_table.h
@@ -109,6 +109,7 @@ static const AVOption avformat_options[] = {
{"dump_separator", "set information dump field separator", OFFSET(dump_separator), AV_OPT_TYPE_STRING, {.str = ", "}, CHAR_MIN, CHAR_MAX, D|E},
{"codec_whitelist", "List of decoders that are allowed to be used", OFFSET(codec_whitelist), AV_OPT_TYPE_STRING, { .str = NULL }, CHAR_MIN, CHAR_MAX, D },
{"format_whitelist", "List of demuxers that are allowed to be used", OFFSET(format_whitelist), AV_OPT_TYPE_STRING, { .str = NULL }, CHAR_MIN, CHAR_MAX, D },
+{"max_streams", "maximum number of streams", OFFSET(max_streams), AV_OPT_TYPE_INT, { .i64 = 1000 }, 0, INT_MAX, D },
{NULL},
};
diff --git a/libavformat/utils.c b/libavformat/utils.c
index a705065879..abc90c3c70 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -3764,8 +3764,11 @@ AVStream *avformat_new_stream(AVFormatContext *s, const AVCodec *c)
int i;
AVStream **streams;
- if (s->nb_streams >= INT_MAX/sizeof(*streams))
+ if (s->nb_streams >= FFMIN(s->max_streams, INT_MAX/sizeof(*streams))) {
+ if (s->max_streams < INT_MAX/sizeof(*streams))
+ av_log(s, AV_LOG_ERROR, "Number of streams exceeds max_streams parameter (%d), see the documentation if you wish to increase it\n", s->max_streams);
return NULL;
+ }
streams = av_realloc_array(s->streams, s->nb_streams + 1, sizeof(*streams));
if (!streams)
return NULL;
diff --git a/libavutil/imgutils.c b/libavutil/imgutils.c
index 9c8216e827..b727b6b5f5 100644
--- a/libavutil/imgutils.c
+++ b/libavutil/imgutils.c
@@ -238,15 +238,34 @@ typedef struct ImgUtils {
static const AVClass imgutils_class = { "IMGUTILS", av_default_item_name, NULL, LIBAVUTIL_VERSION_INT, offsetof(ImgUtils, log_offset), offsetof(ImgUtils, log_ctx) };
-int av_image_check_size(unsigned int w, unsigned int h, int log_offset, void *log_ctx)
+int av_image_check_size2(unsigned int w, unsigned int h, int64_t max_pixels, enum AVPixelFormat pix_fmt, int log_offset, void *log_ctx)
{
ImgUtils imgutils = { &imgutils_class, log_offset, log_ctx };
+ int64_t stride = av_image_get_linesize(pix_fmt, w, 0);
+ if (stride <= 0)
+ stride = 8LL*w;
+ stride += 128*8;
- if ((int)w>0 && (int)h>0 && (w+128)*(uint64_t)(h+128) < INT_MAX/8)
- return 0;
+ if ((int)w<=0 || (int)h<=0 || stride >= INT_MAX || stride*(uint64_t)(h+128) >= INT_MAX) {
+ av_log(&imgutils, AV_LOG_ERROR, "Picture size %ux%u is invalid\n", w, h);
+ return AVERROR(EINVAL);
+ }
- av_log(&imgutils, AV_LOG_ERROR, "Picture size %ux%u is invalid\n", w, h);
- return AVERROR(EINVAL);
+ if (max_pixels < INT64_MAX) {
+ if (w*(int64_t)h > max_pixels) {
+ av_log(&imgutils, AV_LOG_ERROR,
+ "Picture size %ux%u exceeds specified max pixel count %"PRId64", see the documentation if you wish to increase it\n",
+ w, h, max_pixels);
+ return AVERROR(EINVAL);
+ }
+ }
+
+ return 0;
+}
+
+int av_image_check_size(unsigned int w, unsigned int h, int log_offset, void *log_ctx)
+{
+ return av_image_check_size2(w, h, INT64_MAX, AV_PIX_FMT_NONE, log_offset, log_ctx);
}
int av_image_check_sar(unsigned int w, unsigned int h, AVRational sar)
diff --git a/libavutil/imgutils.h b/libavutil/imgutils.h
index 23282a38fa..19f34deced 100644
--- a/libavutil/imgutils.h
+++ b/libavutil/imgutils.h
@@ -192,6 +192,20 @@ int av_image_copy_to_buffer(uint8_t *dst, int dst_size,
int av_image_check_size(unsigned int w, unsigned int h, int log_offset, void *log_ctx);
/**
+ * Check if the given dimension of an image is valid, meaning that all
+ * bytes of the image can be addressed with a signed int.
+ *
+ * @param w the width of the picture
+ * @param h the height of the picture
+ * @param max_pixels the maximum number of pixels the user wants to accept
+ * @param pix_fmt the pixel format, can be AV_PIX_FMT_NONE if unknown.
+ * @param log_offset the offset to sum to the log level for logging with log_ctx
+ * @param log_ctx the parent logging context, it may be NULL
+ * @return >= 0 if valid, a negative error code otherwise
+ */
+int av_image_check_size2(unsigned int w, unsigned int h, int64_t max_pixels, enum AVPixelFormat pix_fmt, int log_offset, void *log_ctx);
+
+/**
* Check if the given sample aspect ratio of an image is valid.
*
* It is considered invalid if the denominator is 0 or if applying the ratio
diff --git a/libavutil/random_seed.c b/libavutil/random_seed.c
index 5af8e9e524..67000e4a1f 100644
--- a/libavutil/random_seed.c
+++ b/libavutil/random_seed.c
@@ -67,6 +67,7 @@ static uint32_t get_generic_seed(void)
uint8_t tmp[120];
struct AVSHA *sha = (void*)tmp;
clock_t last_t = 0;
+ clock_t last_td = 0;
static uint64_t i = 0;
static uint32_t buffer[512] = { 0 };
unsigned char digest[20];
@@ -86,11 +87,12 @@ static uint32_t get_generic_seed(void)
for (;;) {
clock_t t = clock();
-
- if (last_t == t) {
- buffer[i & 511]++;
+ if (last_t + 2*last_td + (CLOCKS_PER_SEC > 1000) >= t) {
+ last_td = t - last_t;
+ buffer[i & 511] = 1664525*buffer[i & 511] + 1013904223 + (last_td % 3294638521U);
} else {
- buffer[++i & 511] += (t - last_t) % 3294638521U;
+ last_td = t - last_t;
+ buffer[++i & 511] += last_td % 3294638521U;
if (last_i && i - last_i > 4 || i - last_i > 64 || TEST && i - last_i > 8)
break;
}
signature.asc
Description: PGP signature
--- End Message ---