diff mbox series

[FFmpeg-devel] avformat/url: fix ff_make_absolute_url with Windows file paths

Message ID 20210402191419.5416-1-cus@passwd.hu
State New
Headers show
Series [FFmpeg-devel] avformat/url: fix ff_make_absolute_url with Windows file paths
Related show

Checks

Context Check Description
andriy/x86_make success Make finished
andriy/x86_make_fate success Make fate finished
andriy/PPC64_make success Make finished
andriy/PPC64_make_fate success Make fate finished

Commit Message

Marton Balint April 2, 2021, 7:14 p.m. UTC
Ugly, but a lot less broken than it was.

Fixes ticket #9166.

Signed-off-by: Marton Balint <cus@passwd.hu>
---
 libavformat/url.c | 25 ++++++++++++++++++++++++-
 1 file changed, 24 insertions(+), 1 deletion(-)

Comments

Marton Balint April 5, 2021, 9:29 a.m. UTC | #1
On Fri, 2 Apr 2021, Marton Balint wrote:

> Ugly, but a lot less broken than it was.
>
> Fixes ticket #9166.

Ping for this, if there is no disapproval of this fix then I plan to 
extend fate and backport this to 4.4/4.3.

Thanks,
Marton

>
> Signed-off-by: Marton Balint <cus@passwd.hu>
> ---
> libavformat/url.c | 25 ++++++++++++++++++++++++-
> 1 file changed, 24 insertions(+), 1 deletion(-)
>
> diff --git a/libavformat/url.c b/libavformat/url.c
> index 77d610d95f..90fd41e810 100644
> --- a/libavformat/url.c
> +++ b/libavformat/url.c
> @@ -149,6 +149,18 @@ int ff_url_decompose(URLComponents *uc, const char *url, const char *end)
>     return 0;
> }
> 
> +static int is_fq_dos_path(const char *path)
> +{
> +    if ((path[0] >= 'a' && path[0] <= 'z' || path[0] >= 'A' && path[0] <= 'Z') &&
> +         path[1] == ':' &&
> +        (path[2] == '/' || path[2] == '\\'))
> +        return 1;
> +    if ((path[0] == '/' || path[0] == '\\') &&
> +        (path[1] == '/' || path[1] == '\\'))
> +        return 1;
> +    return 0;
> +}
> +
> static int append_path(char *root, char *out_end, char **rout,
>                        const char *in, const char *in_end)
> {
> @@ -185,6 +197,7 @@ int ff_make_absolute_url(char *buf, int size, const char *base,
>     char *out, *out_end, *path;
>     const char *keep, *base_path_end;
>     int use_base_path, simplify_path = 0, ret;
> +    const char *base_separators = "/";
>
>     /* This is tricky.
>        For HTTP, http://server/site/page + ../media/file
> @@ -211,6 +224,16 @@ int ff_make_absolute_url(char *buf, int size, const char *base,
>
>     if (!base)
>         base = "";
> +    if (HAVE_DOS_PATHS) {
> +        if ((ret = ff_url_decompose(&ub, base, NULL)) < 0)
> +            goto error;
> +        if (is_fq_dos_path(base) || av_strstart(base, "file:", NULL) || ub.path == ub.url) {
> +            if (is_fq_dos_path(rel))
> +                base = "";
> +            else
> +                base_separators = "/\\";
> +        }
> +    }
>     if ((ret = ff_url_decompose(&ub, base, NULL)) < 0 ||
>         (ret = ff_url_decompose(&uc, rel,  NULL)) < 0)
>         goto error;
> @@ -249,7 +272,7 @@ int ff_make_absolute_url(char *buf, int size, const char *base,
>     if (use_base_path) {
>         base_path_end = ub.url_component_end_path;
>         if (URL_COMPONENT_HAVE(uc, path))
> -            while (base_path_end > ub.path && base_path_end[-1] != '/')
> +            while (base_path_end > ub.path && !strchr(base_separators, base_path_end[-1]))
>                 base_path_end--;
>     }
>     if (keep > ub.path)
> -- 
> 2.26.2
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
diff mbox series

Patch

diff --git a/libavformat/url.c b/libavformat/url.c
index 77d610d95f..90fd41e810 100644
--- a/libavformat/url.c
+++ b/libavformat/url.c
@@ -149,6 +149,18 @@  int ff_url_decompose(URLComponents *uc, const char *url, const char *end)
     return 0;
 }
 
+static int is_fq_dos_path(const char *path)
+{
+    if ((path[0] >= 'a' && path[0] <= 'z' || path[0] >= 'A' && path[0] <= 'Z') &&
+         path[1] == ':' &&
+        (path[2] == '/' || path[2] == '\\'))
+        return 1;
+    if ((path[0] == '/' || path[0] == '\\') &&
+        (path[1] == '/' || path[1] == '\\'))
+        return 1;
+    return 0;
+}
+
 static int append_path(char *root, char *out_end, char **rout,
                        const char *in, const char *in_end)
 {
@@ -185,6 +197,7 @@  int ff_make_absolute_url(char *buf, int size, const char *base,
     char *out, *out_end, *path;
     const char *keep, *base_path_end;
     int use_base_path, simplify_path = 0, ret;
+    const char *base_separators = "/";
 
     /* This is tricky.
        For HTTP, http://server/site/page + ../media/file
@@ -211,6 +224,16 @@  int ff_make_absolute_url(char *buf, int size, const char *base,
 
     if (!base)
         base = "";
+    if (HAVE_DOS_PATHS) {
+        if ((ret = ff_url_decompose(&ub, base, NULL)) < 0)
+            goto error;
+        if (is_fq_dos_path(base) || av_strstart(base, "file:", NULL) || ub.path == ub.url) {
+            if (is_fq_dos_path(rel))
+                base = "";
+            else
+                base_separators = "/\\";
+        }
+    }
     if ((ret = ff_url_decompose(&ub, base, NULL)) < 0 ||
         (ret = ff_url_decompose(&uc, rel,  NULL)) < 0)
         goto error;
@@ -249,7 +272,7 @@  int ff_make_absolute_url(char *buf, int size, const char *base,
     if (use_base_path) {
         base_path_end = ub.url_component_end_path;
         if (URL_COMPONENT_HAVE(uc, path))
-            while (base_path_end > ub.path && base_path_end[-1] != '/')
+            while (base_path_end > ub.path && !strchr(base_separators, base_path_end[-1]))
                 base_path_end--;
     }
     if (keep > ub.path)