[FFmpeg-devel] [PATCH] lavf/dashenc: Fix file URI handling when deleting files.

Andrey Semashev andrey.semashev at gmail.com
Wed Nov 28 13:16:49 EET 2018


The URI used to open the output streams may be an actual URI with "file" scheme,
according to https://tools.ietf.org/html/rfc8089. This commit makes file
deletion routine recognize file URIs and extract the actual filesystem path
from it.

It also fixes strerror use, which may not be thread-safe.
---
 libavformat/dashenc.c | 29 +++++++++++++++++++++++++++--
 1 file changed, 27 insertions(+), 2 deletions(-)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 6ce70e0076..e59fa0944e 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -25,6 +25,7 @@
 #include <unistd.h>
 #endif
 
+#include "libavutil/error.h"
 #include "libavutil/avassert.h"
 #include "libavutil/avutil.h"
 #include "libavutil/avstring.h"
@@ -1326,8 +1327,32 @@ static void dashenc_delete_file(AVFormatContext *s, char *filename) {
 
         av_dict_free(&http_opts);
         ff_format_io_close(s, &out);
-    } else if (unlink(filename) < 0) {
-        av_log(s, AV_LOG_ERROR, "failed to delete %s: %s\n", filename, strerror(errno));
+    } else {
+        const char* path = filename;
+        // Check if the filename is a file URI. https://tools.ietf.org/html/rfc8089#section-2
+        if (av_strncasecmp(path, "file:", sizeof("file:") - 1) == 0) {
+            path += sizeof("file:") - 1;
+            if (path[0] == '/' && path[1] == '/') {
+                // The URI may have an authority part. Check that the authority does not contain
+                // a host name. We cannot access filesystem on a different host.
+                path += 2;
+                if (path[0] != '/') {
+                    if (strncmp(path, "localhost", sizeof("localhost") - 1) == 0) {
+                        path += sizeof("localhost") - 1;
+                    } else {
+                        av_log(s, AV_LOG_ERROR, "cannot delete file on a remote host: %s\n", filename);
+                        return;
+                    }
+                }
+            }
+        }
+
+        if (unlink(path) < 0) {
+            int err = AVERROR(errno);
+            char errbuf[128];
+            av_strerror(err, errbuf, sizeof(errbuf));
+            av_log(s, (err == AVERROR(ENOENT) ? AV_LOG_WARNING : AV_LOG_ERROR), "failed to delete %s: %s\n", path, errbuf);
+        }
     }
 }
 
-- 
2.19.1



More information about the ffmpeg-devel mailing list