diff mbox series

[FFmpeg-devel,2/2] avformat/url: add ff_make_absolulte_url2 to be able to test windows path cases

Message ID 20210405232456.6367-2-cus@passwd.hu
State Accepted
Commit fb4da90fecdefa2508618ca835cd0250be940e04
Headers show
Series [FFmpeg-devel,1/2] 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 5, 2021, 11:24 p.m. UTC
Signed-off-by: Marton Balint <cus@passwd.hu>
---
 libavformat/tests/url.c | 33 ++++++++++++++++++++++++++++++---
 libavformat/url.c       | 12 +++++++++---
 libavformat/url.h       | 10 ++++++++++
 tests/ref/fate/url      | 20 ++++++++++++++++++++
 4 files changed, 69 insertions(+), 6 deletions(-)
diff mbox series

Patch

diff --git a/libavformat/tests/url.c b/libavformat/tests/url.c
index 2eb597bb5e..8644a3e826 100644
--- a/libavformat/tests/url.c
+++ b/libavformat/tests/url.c
@@ -18,6 +18,7 @@ 
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "config.h"
 #include "libavformat/url.h"
 #include "libavformat/avformat.h"
 
@@ -48,19 +49,30 @@  static void test_decompose(const char *url)
 
 static void test(const char *base, const char *rel)
 {
-    char buf[200], buf2[200];
+    char buf[200], buf2[200], buf_dos[200], buf_native[200];
     int ret;
 
-    ret = ff_make_absolute_url(buf, sizeof(buf), base, rel);
+    ret = ff_make_absolute_url2(buf, sizeof(buf), base, rel, 0);
     if (ret < 0) {
         printf("%50s %-20s => error %s\n", base, rel, av_err2str(ret));
         return;
     }
     printf("%50s %-20s => %s\n", base, rel, buf);
+    ret = ff_make_absolute_url2(buf_dos, sizeof(buf_dos), base, rel, 1);
+    if (ret < 0)
+        snprintf(buf_dos, sizeof(buf_dos), "error %s", av_err2str(ret));
+    ret = ff_make_absolute_url(buf_native, sizeof(buf_native), base, rel);
+    if (ret < 0)
+        snprintf(buf_native, sizeof(buf_native), "error %s", av_err2str(ret));
+    if (strcmp(buf, buf_dos))
+        printf("%50s %-20sDOS %s\n", base, rel, buf_dos);
+    if (HAVE_DOS_PATHS && strcmp(buf_dos, buf_native) ||
+        !HAVE_DOS_PATHS && strcmp(buf, buf_native))
+        printf("Native mismatch\n");
     if (base) {
         /* Test in-buffer replacement */
         snprintf(buf2, sizeof(buf2), "%s", base);
-        ff_make_absolute_url(buf2, sizeof(buf2), buf2, rel);
+        ff_make_absolute_url2(buf2, sizeof(buf2), buf2, rel, 0);
         if (strcmp(buf, buf2)) {
             printf("In-place handling of %s + %s failed\n", base, rel);
             exit(1);
@@ -121,6 +133,21 @@  int main(void)
     test("http://server/foo/bar", "..doubledotfile");
     test("http://server/foo/bar", "double..dotfile");
     test("http://server/foo/bar", "doubledotfile..");
+    test("file1", "file2");
+    test("dir/file1", "file2");
+    test("dir/file1", "../file2");
+    test("dir\\file1", "file2");
+    test("\\\\srv\\shr\\file", "..\\..\\dummy");
+    test("\\\\srv\\shr\\file", "dummy");
+    test("\\\\srv\\shr\\file", "\\\\srv2\\shr2\\file2");
+    test("\\\\srv\\shr\\file", "d:/file");
+    test("C:\\dir\\a", "..\\file");
+    test("C:\\dir\\a", "\\\\srv\\shr\\file");
+    test("C:\\dir\\a", "d:\\file");
+    test("http://a/b", "\\\\srv\\shr\\file");
+    test("http://a/b", "//srv/shr/file");
+    test("http://a/b", "d:\\file");
+    test("http://a/b", "C:/file");
 
     /* From https://tools.ietf.org/html/rfc3986#section-5.4 */
     test("http://a/b/c/d;p?q", "g:h");           // g:h
diff --git a/libavformat/url.c b/libavformat/url.c
index 222d7d8a10..f53fdf59d8 100644
--- a/libavformat/url.c
+++ b/libavformat/url.c
@@ -190,8 +190,8 @@  static int append_path(char *root, char *out_end, char **rout,
     return 0;
 }
 
-int ff_make_absolute_url(char *buf, int size, const char *base,
-                          const char *rel)
+int ff_make_absolute_url2(char *buf, int size, const char *base,
+                          const char *rel, int handle_dos_paths)
 {
     URLComponents ub, uc;
     char *out, *out_end, *path;
@@ -224,7 +224,7 @@  int ff_make_absolute_url(char *buf, int size, const char *base,
 
     if (!base)
         base = "";
-    if (HAVE_DOS_PATHS) {
+    if (handle_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) {
@@ -316,6 +316,12 @@  error:
     return ret;
 }
 
+int ff_make_absolute_url(char *buf, int size, const char *base,
+                         const char *rel)
+{
+    return ff_make_absolute_url2(buf, size, base, rel, HAVE_DOS_PATHS);
+}
+
 AVIODirEntry *ff_alloc_dir_entry(void)
 {
     AVIODirEntry *entry = av_mallocz(sizeof(AVIODirEntry));
diff --git a/libavformat/url.h b/libavformat/url.h
index f13e851a14..3bb1cf89f7 100644
--- a/libavformat/url.h
+++ b/libavformat/url.h
@@ -308,6 +308,16 @@  int ff_url_join(char *str, int size, const char *proto,
  * @param size the size of buf
  * @param base the base url, may be equal to buf.
  * @param rel the new url, which is interpreted relative to base
+ * @param handle_dos_paths handle DOS paths for file or unspecified protocol
+ */
+int ff_make_absolute_url2(char *buf, int size, const char *base,
+                         const char *rel, int handle_dos_paths);
+
+/**
+ * Convert a relative url into an absolute url, given a base url.
+ *
+ * Same as ff_make_absolute_url2 with handle_dos_paths being equal to
+ * HAVE_DOS_PATHS config variable.
  */
 int ff_make_absolute_url(char *buf, int size, const char *base,
                          const char *rel);
diff --git a/tests/ref/fate/url b/tests/ref/fate/url
index 08e80def7d..8489d10968 100644
--- a/tests/ref/fate/url
+++ b/tests/ref/fate/url
@@ -79,6 +79,26 @@  Testing ff_make_absolute_url:
                              http://server/foo/bar ..doubledotfile      => http://server/foo/..doubledotfile
                              http://server/foo/bar double..dotfile      => http://server/foo/double..dotfile
                              http://server/foo/bar doubledotfile..      => http://server/foo/doubledotfile..
+                                             file1 file2                => file2
+                                         dir/file1 file2                => dir/file2
+                                         dir/file1 ../file2             => dir/../file2
+                                         dir\file1 file2                => file2
+                                         dir\file1 file2               DOS dir\file2
+                                    \\srv\shr\file ..\..\dummy          => ..\..\dummy
+                                    \\srv\shr\file ..\..\dummy         DOS \\srv\shr\..\..\dummy
+                                    \\srv\shr\file dummy                => dummy
+                                    \\srv\shr\file dummy               DOS \\srv\shr\dummy
+                                    \\srv\shr\file \\srv2\shr2\file2    => \\srv2\shr2\file2
+                                    \\srv\shr\file d:/file              => d:/file
+                                          C:\dir\a ..\file              => C:..\file
+                                          C:\dir\a ..\file             DOS C:\dir\..\file
+                                          C:\dir\a \\srv\shr\file       => C:\\srv\shr\file
+                                          C:\dir\a \\srv\shr\file      DOS \\srv\shr\file
+                                          C:\dir\a d:\file              => d:\file
+                                        http://a/b \\srv\shr\file       => http://a/\\srv\shr\file
+                                        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 g                    => http://a/b/c/g
                                 http://a/b/c/d;p?q ./g                  => http://a/b/c/g