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

Reply via email to