[vlc-commits] url: fix parsing URIs without authority

Rémi Denis-Courmont git at videolan.org
Sun Jul 17 16:13:56 CEST 2016


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sun Jul 17 16:41:34 2016 +0300| [6a86b34f6944bfe69a4a73f789058093a832b7e6] | committer: Rémi Denis-Courmont

url: fix parsing URIs without authority

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

 src/text/url.c |  112 +++++++++++++++++++++++++++++---------------------------
 1 file changed, 59 insertions(+), 53 deletions(-)

diff --git a/src/text/url.c b/src/text/url.c
index d3f33b5..f5f7ba6 100644
--- a/src/text/url.c
+++ b/src/text/url.c
@@ -387,20 +387,15 @@ void vlc_UrlParse (vlc_url_t *restrict url, const char *str)
 
     char *cur = buf, *next;
 
-    /* URL scheme */
+    /* URI scheme */
     next = buf;
     while ((*next >= 'A' && *next <= 'Z') || (*next >= 'a' && *next <= 'z')
         || (*next >= '0' && *next <= '9') || memchr ("+-.", *next, 3) != NULL)
         next++;
-    /* This is not strictly correct. In principles, the scheme is always
-     * present in an absolute URL and followed by a colon. Depending on the
-     * URL scheme, the two subsequent slashes are not required.
-     * VLC uses a different scheme for historical compatibility reasons - the
-     * scheme is often implicit. */
-    if (!strncmp (next, "://", 3))
+
+    if (*next == ':')
     {
-        *next = '\0';
-        next += 3;
+        *(next++) = '\0';
         url->psz_protocol = cur;
         cur = next;
     }
@@ -413,66 +408,77 @@ void vlc_UrlParse (vlc_url_t *restrict url, const char *str)
         url->psz_option = query;
     }
 
-    /* Path */
-    next = strchr (cur, '/');
-    if (next != NULL)
+    /* Authority */
+    if (strncmp(cur, "//", 2) == 0)
     {
-        *next = '\0'; /* temporary nul, reset to slash later */
-        url->psz_path = next;
-    }
-    /*else
-        url->psz_path = "/";*/
+        cur += 2;
 
-    /* User name */
-    next = strrchr (cur, '@');
-    if (next != NULL)
-    {
-        *(next++) = '\0';
-        url->psz_username = cur;
-        cur = next;
+        /* Path */
+        next = strchr(cur, '/');
+        if (next != NULL)
+        {
+            *next = '\0'; /* temporary nul, reset to slash later */
+            url->psz_path = next;
+        }
+        /*else
+            url->psz_path = "/";*/
 
-        /* Password (obsolete) */
-        next = strchr (url->psz_username, ':');
+        /* User name */
+        next = strrchr(cur, '@');
         if (next != NULL)
         {
             *(next++) = '\0';
-            url->psz_password = next;
-            vlc_uri_decode (url->psz_password);
+            url->psz_username = cur;
+            cur = next;
+
+            /* Password (obsolete) */
+            next = strchr(url->psz_username, ':');
+            if (next != NULL)
+            {
+                *(next++) = '\0';
+                url->psz_password = next;
+                vlc_uri_decode(url->psz_password);
+            }
+            vlc_uri_decode(url->psz_username);
         }
-        vlc_uri_decode (url->psz_username);
-    }
 
-    /* Host name */
-    if (*cur == '[' && (next = strrchr (cur, ']')) != NULL)
-    {   /* Try IPv6 numeral within brackets */
-        *(next++) = '\0';
-        url->psz_host = strdup (cur + 1);
+        /* Host name */
+        if (*cur == '[' && (next = strrchr(cur, ']')) != NULL)
+        {   /* Try IPv6 numeral within brackets */
+            *(next++) = '\0';
+            url->psz_host = strdup(cur + 1);
 
-        if (*next == ':')
-            next++;
+            if (*next == ':')
+                next++;
+            else
+                next = NULL;
+        }
         else
-            next = NULL;
-    }
-    else
-    {
-        next = strchr (cur, ':');
+        {
+            next = strchr(cur, ':');
+            if (next != NULL)
+                *(next++) = '\0';
+
+            url->psz_host = vlc_idna_to_ascii (cur);
+        }
+        if (!vlc_uri_host_validate(url->psz_host))
+        {
+            free(url->psz_host);
+            url->psz_host = NULL;
+        }
+
+        /* Port number */
         if (next != NULL)
-            *(next++) = '\0';
+            url->i_port = atoi(next);
 
-        url->psz_host = vlc_idna_to_ascii (cur);
+        if (url->psz_path != NULL)
+            *url->psz_path = '/'; /* restore leading slash */
     }
-    if (!vlc_uri_host_validate(url->psz_host))
+    else
     {
-        free(url->psz_host);
-        url->psz_host = NULL;
+        url->psz_path = cur;
     }
 
-    /* Port number */
-    if (next != NULL)
-        url->i_port = atoi (next);
-
-    if (url->psz_path != NULL)
-        *url->psz_path = '/'; /* restore leading slash */
     if (!vlc_uri_path_validate(url->psz_path))
         url->psz_path = NULL;
 }



More information about the vlc-commits mailing list