[vlc-commits] url: add vlc_UrlParseFixup

Thomas Guillem git at videolan.org
Wed Dec 6 10:13:24 CET 2017


vlc | branch: master | Thomas Guillem <thomas at gllm.fr> | Mon Dec  4 13:56:41 2017 +0100| [ba9809c8b83163098c097d4275ddc6e3b662c412] | committer: Thomas Guillem

url: add vlc_UrlParseFixup

Refs #18991

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=ba9809c8b83163098c097d4275ddc6e3b662c412
---

 include/vlc_url.h  |  9 +++++++++
 src/libvlccore.sym |  1 +
 src/text/url.c     | 56 ++++++++++++++++++++++++++++++++++++++++++++++++------
 3 files changed, 60 insertions(+), 6 deletions(-)

diff --git a/include/vlc_url.h b/include/vlc_url.h
index 5a20c27edc..e13b7a5abb 100644
--- a/include/vlc_url.h
+++ b/include/vlc_url.h
@@ -153,6 +153,7 @@ struct vlc_url_t
     char *psz_option;
 
     char *psz_buffer; /* to be freed */
+    char *psz_pathbuffer; /* to be freed */
 };
 
 /**
@@ -192,6 +193,14 @@ struct vlc_url_t
 VLC_API int vlc_UrlParse(vlc_url_t *url, const char *str);
 
 /**
+ * Parses an URI or IRI and fix up the path part.
+ *
+ * \see vlc_UrlParse
+ * \see vlc_uri_fixup
+ */
+VLC_API int vlc_UrlParseFixup(vlc_url_t *url, const char *str);
+
+/**
  * Releases resources allocated by vlc_UrlParse().
  */
 VLC_API void vlc_UrlClean(vlc_url_t *);
diff --git a/src/libvlccore.sym b/src/libvlccore.sym
index 3e0d23fdf0..a15ba0d923 100644
--- a/src/libvlccore.sym
+++ b/src/libvlccore.sym
@@ -235,6 +235,7 @@ libvlc_MetadataRequest
 libvlc_MetadataCancel
 libvlc_ArtRequest
 vlc_UrlParse
+vlc_UrlParseFixup
 vlc_UrlClean
 vlc_path2uri
 vlc_uri2path
diff --git a/src/text/url.c b/src/text/url.c
index dc983c8861..1c86bedb58 100644
--- a/src/text/url.c
+++ b/src/text/url.c
@@ -401,7 +401,7 @@ static bool vlc_uri_path_validate(const char *str)
     return vlc_uri_component_validate(str, "/@:");
 }
 
-int vlc_UrlParse(vlc_url_t *restrict url, const char *str)
+static int vlc_UrlParseInner(vlc_url_t *restrict url, const char *str)
 {
     url->psz_protocol = NULL;
     url->psz_username = NULL;
@@ -411,6 +411,7 @@ int vlc_UrlParse(vlc_url_t *restrict url, const char *str)
     url->psz_path = NULL;
     url->psz_option = NULL;
     url->psz_buffer = NULL;
+    url->psz_pathbuffer = NULL;
 
     if (str == NULL)
     {
@@ -547,13 +548,46 @@ int vlc_UrlParse(vlc_url_t *restrict url, const char *str)
         url->psz_path = cur;
     }
 
+    return ret;
+}
+
+int vlc_UrlParse(vlc_url_t *url, const char *str)
+{
+    int ret = vlc_UrlParseInner(url, str);
+
     if (url->psz_path != NULL && !vlc_uri_path_validate(url->psz_path))
     {
         url->psz_path = NULL;
         errno = EINVAL;
         ret = -1;
     }
+    return ret;
+}
+
+static char *vlc_uri_fixup_inner(const char *str, const char *extras);
 
+int vlc_UrlParseFixup(vlc_url_t *url, const char *str)
+{
+    int ret = vlc_UrlParseInner(url, str);
+
+    static const char pathextras[] = "/@:";
+
+    if (url->psz_path != NULL
+     && !vlc_uri_component_validate(url->psz_path, pathextras))
+    {
+        url->psz_pathbuffer = vlc_uri_fixup_inner(url->psz_path, pathextras);
+        if (url->psz_pathbuffer == NULL)
+        {
+            url->psz_path = NULL;
+            errno = ENOMEM;
+            ret = -1;
+        }
+        else
+        {
+            url->psz_path = url->psz_pathbuffer;
+            assert(vlc_uri_path_validate(url->psz_path));
+        }
+    }
     return ret;
 }
 
@@ -561,6 +595,7 @@ void vlc_UrlClean (vlc_url_t *restrict url)
 {
     free (url->psz_host);
     free (url->psz_buffer);
+    free (url->psz_pathbuffer);
 }
 
 /**
@@ -793,11 +828,9 @@ error:
     return ret;
 }
 
-char *vlc_uri_fixup(const char *str)
+static char *vlc_uri_fixup_inner(const char *str, const char *extras)
 {
-    /* Rule number one is do not change a (potentially) valid URI */
-    if (vlc_uri_component_validate(str, ":/?#[]@"))
-        return strdup(str);
+    assert(str && extras);
 
     bool encode_percent = false;
     for (size_t i = 0; str[i] != '\0'; i++)
@@ -815,7 +848,7 @@ char *vlc_uri_fixup(const char *str)
     {
         unsigned char c = str[i];
 
-        if (isurisafe(c) || isurisubdelim(c) || (strchr(":/?#[]@", c) != NULL)
+        if (isurisafe(c) || isurisubdelim(c) || (strchr(extras, c) != NULL)
          || (c == '%' && !encode_percent))
             vlc_memstream_putc(&stream, c);
         else
@@ -827,6 +860,17 @@ char *vlc_uri_fixup(const char *str)
     return stream.ptr;
 }
 
+char *vlc_uri_fixup(const char *str)
+{
+    static const char extras[] = ":/?#[]@";
+
+    /* Rule number one is do not change a (potentially) valid URI */
+    if (vlc_uri_component_validate(str, extras))
+        return strdup(str);
+
+    return vlc_uri_fixup_inner(str, extras);
+}
+
 #if defined (HAVE_IDN)
 # include <idna.h>
 #elif defined (_WIN32)



More information about the vlc-commits mailing list