diff options
author | Luca Barbato <lu_zero@gentoo.org> | 2015-01-05 10:40:41 +0100 |
---|---|---|
committer | Luca Barbato <lu_zero@gentoo.org> | 2015-01-07 12:36:28 +0100 |
commit | b3f04657368a32a9903406395f865e230b1de348 (patch) | |
tree | e80c90201dbb9e2f0ac0b69b9fc45a0af194559e | |
parent | 8a3d9ca603f4d15ecaa9ca379cbaab4ecaec8ce4 (diff) | |
download | ffmpeg-b3f04657368a32a9903406395f865e230b1de348.tar.gz |
segment: Fix the failure paths
A failure in segment_end() or segment_start() would lead to freeing
a dangling pointer and in general further calls to seg_write_packet()
or to seg_write_trailer() would have the same faulty behaviour.
CC: libav-stable@libav.org
Reported-By: luodalongde@gmail.com
-rw-r--r-- | libavformat/segment.c | 32 |
1 files changed, 20 insertions, 12 deletions
diff --git a/libavformat/segment.c b/libavformat/segment.c index 52da6b9ce3..bcfd1f9973 100644 --- a/libavformat/segment.c +++ b/libavformat/segment.c @@ -184,6 +184,13 @@ static void close_null_ctx(AVIOContext *pb) av_free(pb); } +static void seg_free_context(SegmentContext *seg) +{ + avio_closep(&seg->pb); + avformat_free_context(seg->avf); + seg->avf = NULL; +} + static int seg_write_header(AVFormatContext *s) { SegmentContext *seg = s->priv_data; @@ -265,12 +272,9 @@ static int seg_write_header(AVFormatContext *s) } fail: - if (ret) { - if (seg->list) - avio_close(seg->pb); - if (seg->avf) - avformat_free_context(seg->avf); - } + if (ret < 0) + seg_free_context(seg); + return ret; } @@ -282,6 +286,9 @@ static int seg_write_packet(AVFormatContext *s, AVPacket *pkt) int64_t end_pts = seg->recording_time * seg->number; int ret, can_split = 1; + if (!oc) + return AVERROR(EINVAL); + if (seg->has_video) { can_split = st->codec->codec_type == AVMEDIA_TYPE_VIDEO && pkt->flags & AV_PKT_FLAG_KEY; @@ -322,11 +329,8 @@ static int seg_write_packet(AVFormatContext *s, AVPacket *pkt) ret = ff_write_chained(oc, pkt->stream_index, pkt, s); fail: - if (ret < 0) { - if (seg->list) - avio_close(seg->pb); - avformat_free_context(oc); - } + if (ret < 0) + seg_free_context(seg); return ret; } @@ -335,7 +339,11 @@ static int seg_write_trailer(struct AVFormatContext *s) { SegmentContext *seg = s->priv_data; AVFormatContext *oc = seg->avf; - int ret; + int ret = 0; + + if (!oc) + goto fail; + if (!seg->write_header_trailer) { if ((ret = segment_end(oc, 0)) < 0) goto fail; |