On Thu, 24 Mar 2016, Jan Sebechlebsky wrote:

Calling close_slave in case error is to be returned from open_slave
will free allocated resources.

Since failure can happen before bsfs array is initialized,
close_slave must check that bsfs is not NULL before accessing
tee_slave->bsfs[i] element.

Signed-off-by: Jan Sebechlebsky <sebechlebsky...@gmail.com>
---
libavformat/tee.c | 22 ++++++++++++++--------
1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/libavformat/tee.c b/libavformat/tee.c
index 09551b3..e43ef08 100644
--- a/libavformat/tee.c
+++ b/libavformat/tee.c
@@ -141,12 +141,14 @@ static void close_slave(TeeSlave* tee_slave)
    unsigned i;

    avf = tee_slave->avf;
-    for (i=0; i < avf->nb_streams; ++i) {
-        AVBitStreamFilterContext *bsf_next, *bsf = tee_slave->bsfs[i];
-        while (bsf) {
-            bsf_next = bsf->next;
-            av_bitstream_filter_close(bsf);
-            bsf = bsf_next;
+    if (tee_slave->bsfs) {
+        for (i=0; i < avf->nb_streams; ++i) {
+            AVBitStreamFilterContext *bsf_next, *bsf = tee_slave->bsfs[i];
+            while (bsf) {
+                bsf_next = bsf->next;
+                av_bitstream_filter_close(bsf);
+                bsf = bsf_next;
+            }
        }
    }
    av_freep(&tee_slave->stream_map);
@@ -198,6 +200,7 @@ static int open_slave(AVFormatContext *avf, char *slave, 
TeeSlave *tee_slave)
    ret = avformat_alloc_output_context2(&avf2, NULL, format, filename);
    if (ret < 0)
        goto end;
+    tee_slave->avf = avf2;
    av_dict_copy(&avf2->metadata, avf->metadata, 0);
    avf2->opaque   = avf->opaque;
    avf2->io_open  = avf->io_open;
@@ -277,7 +280,6 @@ static int open_slave(AVFormatContext *avf, char *slave, 
TeeSlave *tee_slave)
        goto end;
    }

-    tee_slave->avf = avf2;
    tee_slave->bsfs = av_calloc(avf2->nb_streams, sizeof(TeeSlave));
    if (!tee_slave->bsfs) {
        ret = AVERROR(ENOMEM);
@@ -292,7 +294,8 @@ static int open_slave(AVFormatContext *avf, char *slave, 
TeeSlave *tee_slave)
                av_log(avf, AV_LOG_ERROR,
                       "Specifier separator in '%s' is '%c', but only characters 
'%s' "
                       "are allowed\n", entry->key, *spec, slave_bsfs_spec_sep);
-                return AVERROR(EINVAL);
+                ret = AVERROR(EINVAL);
+                goto end;
            }
            spec++; /* consume separator */
        }
@@ -337,6 +340,9 @@ static int open_slave(AVFormatContext *avf, char *slave, 
TeeSlave *tee_slave)
    }

end:
+    if ( ret < 0 ){
+        close_slave(tee_slave);
+    }

Do you really need to call close_slave here? As far as I see if open_slave fails then the failure path of tee_write_header will call close_slaves, so the streams will be closed, therefore no need to do it here.

Regards,
Marton
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Reply via email to