[FFmpeg-devel] [PATCH] Accept a colon in the path of a URI, instead of stripping preceding characters.

Timothy Allen tim at treehouse.org.za
Tue May 20 18:27:37 EEST 2025


This commit closes trac ticket 10679.

Signed-off-by: Timothy Allen <tim at treehouse.org.za>
---
 libavformat/tests/url.c | 8 +++++++-
 libavformat/url.c       | 8 +++++++-
 tests/ref/fate/url      | 7 ++++++-
 3 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/libavformat/tests/url.c b/libavformat/tests/url.c
index 8644a3e826..8bc3aab6be 100644
--- a/libavformat/tests/url.c
+++ b/libavformat/tests/url.c
@@ -148,9 +148,15 @@ int main(void)
     test("http://a/b", "//srv/shr/file");
     test("http://a/b", "d:\\file");
     test("http://a/b", "C:/file");
+    test("http://a:b/c/d;p?q", "e");             // http://a:b/c/e
+    test("http://a:b/c/d;p?q", "e:f/g");         // http://a:d/c/e:f/g
+    test("http://u:w@a:p/b/c/d", "e");           // http://u:w@a/b/c/e
+    test("http://u:w@a:p/b/c/d", "/e");          // http://u:w@a/e
+    test("", "g:h");                             // g:h
+    test("http://a/b/c/d;p?q", "g:h");           // http://a/b/c/g:h
 
     /* From https://tools.ietf.org/html/rfc3986#section-5.4 */
-    test("http://a/b/c/d;p?q", "g:h");           // g:h
+    //test("http://a/b/c/d;p?q", "g:h");           // g:h
     test("http://a/b/c/d;p?q", "g");             // http://a/b/c/g
     test("http://a/b/c/d;p?q", "./g");           // http://a/b/c/g
     test("http://a/b/c/d;p?q", "g/");            // http://a/b/c/g/
diff --git a/libavformat/url.c b/libavformat/url.c
index d5dd6a4666..abcd3d2366 100644
--- a/libavformat/url.c
+++ b/libavformat/url.c
@@ -100,7 +100,13 @@ int ff_url_decompose(URLComponents *uc, const char *url, const char *end)
     /* scheme */
     uc->scheme = cur;
     p = find_delim(":/?#", cur, end); /* lavf "schemes" can contain options but not some RFC 3986 delimiters */
-    if (*p == ':')
+    /* A colon can indicate a separator for the scheme
+       (https://host/), or the userinfo (user:pass at host/), or
+       the host/port (host:port). It can also be valid within the
+       path. To distinguish the scheme, require it to be followed
+       by a slash to indicate the scheme.
+     */
+    if (*p == ':' && (p[1] == '/' || p[1] == '\\' || p[1] == '.'))
         cur = p + 1;
 
     /* authority */
diff --git a/tests/ref/fate/url b/tests/ref/fate/url
index 8489d10968..229f9815f5 100644
--- a/tests/ref/fate/url
+++ b/tests/ref/fate/url
@@ -99,7 +99,12 @@ Testing ff_make_absolute_url:
                                         http://a/b //srv/shr/file       => http://srv/shr/file
                                         http://a/b d:\file              => d:\file
                                         http://a/b C:/file              => C:/file
-                                http://a/b/c/d;p?q g:h                  => g:h
+                                http://a:b/c/d;p?q e                    => http://a:b/c/e
+                                http://a:b/c/d;p?q e:f/g                => http://a:b/c/e:f/g
+                              http://u:w@a:p/b/c/d e                    => http://u:w@a:p/b/c/e
+                              http://u:w@a:p/b/c/d /e                   => http://u:w@a:p/e
+                                                   g:h                  => g:h
+                                http://a/b/c/d;p?q g:h                  => http://a/b/c/g:h
                                 http://a/b/c/d;p?q g                    => http://a/b/c/g
                                 http://a/b/c/d;p?q ./g                  => http://a/b/c/g
                                 http://a/b/c/d;p?q g/                   => http://a/b/c/g/
-- 
2.43.0


More information about the ffmpeg-devel mailing list