Module: libav Branch: release/0.8 Commit: cdd0eef776ce9d24d73ccb4a890b2a88280f5733
Author: Luca Barbato <[email protected]> Committer: Diego Biurrun <[email protected]> Date: Mon Jan 5 10:40:41 2015 +0100 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: [email protected] Reported-By: [email protected] (cherry picked from commit b3f04657368a32a9903406395f865e230b1de348) Signed-off-by: Diego Biurrun <[email protected]> --- libavformat/segment.c | 42 +++++++++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/libavformat/segment.c b/libavformat/segment.c index 89ae62d..7b3adaf 100644 --- a/libavformat/segment.c +++ b/libavformat/segment.c @@ -99,6 +99,20 @@ static int segment_end(AVFormatContext *oc) return ret; } +static int avio_closep(AVIOContext **s) +{ + int ret = avio_close(*s); + *s = NULL; + return ret; +} + +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; @@ -169,13 +183,9 @@ static int seg_write_header(AVFormatContext *s) } fail: - if (ret) { - oc->streams = NULL; - oc->nb_streams = 0; - if (seg->list) - avio_close(seg->pb); - avformat_free_context(oc); - } + if (ret < 0) + seg_free_context(seg); + return ret; } @@ -187,6 +197,9 @@ static int seg_write_packet(AVFormatContext *s, AVPacket *pkt) int64_t end_pts = seg->recording_time * seg->number; int ret; + if (!oc) + return AVERROR(EINVAL); + if ((seg->has_video && st->codec->codec_type == AVMEDIA_TYPE_VIDEO) && av_compare_ts(pkt->pts, st->time_base, end_pts, AV_TIME_BASE_Q) >= 0 && @@ -219,13 +232,8 @@ static int seg_write_packet(AVFormatContext *s, AVPacket *pkt) ret = oc->oformat->write_packet(oc, pkt); fail: - if (ret < 0) { - oc->streams = NULL; - oc->nb_streams = 0; - if (seg->list) - avio_close(seg->pb); - avformat_free_context(oc); - } + if (ret < 0) + seg_free_context(seg); return ret; } @@ -234,12 +242,16 @@ static int seg_write_trailer(struct AVFormatContext *s) { SegmentContext *seg = s->priv_data; AVFormatContext *oc = seg->avf; - int ret = segment_end(oc); + int ret = 0; + if (!oc) + goto fail; + ret = segment_end(oc); if (seg->list) avio_close(seg->pb); oc->streams = NULL; oc->nb_streams = 0; avformat_free_context(oc); +fail: return ret; } _______________________________________________ libav-commits mailing list [email protected] https://lists.libav.org/mailman/listinfo/libav-commits
