[FFmpeg-devel] [PATCH 09/10] lavf/file: handle standard file:// URLs.

Nicolas George george at nsup.org
Tue Jul 27 17:48:12 EEST 2021


Signed-off-by: Nicolas George <george at nsup.org>
---
 libavformat/file.c | 54 +++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 53 insertions(+), 1 deletion(-)

diff --git a/libavformat/file.c b/libavformat/file.c
index 2fb93c23fd..82d9e7bab4 100644
--- a/libavformat/file.c
+++ b/libavformat/file.c
@@ -20,6 +20,7 @@
  */
 
 #include "libavutil/avstring.h"
+#include "libavutil/bprint.h"
 #include "libavutil/internal.h"
 #include "libavutil/opt.h"
 #include "avformat.h"
@@ -355,10 +356,61 @@ static int file_close_dir(URLContext *h)
 
 #if CONFIG_FILE_PROTOCOL
 
+/**
+ * De-escape %hh. Return 0 if no de-escaping needed.
+ */
+static int url_de_escape(void *log, const char *filename, AVBPrint *out)
+{
+    const char *in;
+
+    for (in = filename; *in; in++)
+        if (*in == '%' || *in == '#' || *in == '?')
+            break;
+    if (!*in)
+        return 0;
+    for (in = filename; *in; in++) {
+        if (*in == '#' || *in == '?')
+            break;
+        if (*in == '%') {
+            int a = ff_hexpair2int(in + 1);
+            if (a < 0) {
+                av_log(log, AV_LOG_ERROR, "Invalid %% char in URL.\n");
+                return AVERROR(EINVAL);
+            }
+            av_bprint_chars(out, a, 1);
+            in += 2;
+        } else {
+            av_bprint_chars(out, *in, 1);
+        }
+    }
+    if (!av_bprint_is_complete(out))
+        return AVERROR(ENOMEM);
+    return 1;
+}
+
 static int file_open(URLContext *h, const char *filename, int flags)
 {
+    AVBPrint decoded;
+    int ret;
+
     av_strstart(filename, "file:", &filename);
-    return file_open_common(h, filename, flags);
+    av_bprint_init(&decoded, 1, AV_BPRINT_SIZE_UNLIMITED);
+    if (filename[0] == '/' && filename[1] == '/' && filename[2] == '/') {
+        filename += 2;
+        ret = url_de_escape(h, filename, &decoded);
+        if (ret < 0) {
+            av_bprint_finalize(&decoded, NULL);
+            return ret;
+        }
+        if (ret)
+            filename = decoded.str;
+    } else {
+        av_log(h, AV_LOG_WARNING,
+               "'file:path' is deprecated, use 'fs:path' or a standard 'file:///' URL\n");
+    }
+    ret = file_open_common(h, filename, flags);
+    av_bprint_finalize(&decoded, NULL);
+    return ret;
 }
 
 const URLProtocol ff_file_protocol = {
-- 
2.30.2



More information about the ffmpeg-devel mailing list