[vlc-devel] [PATCH 1/4] vlc_url: parse '@[bindhost]:[bindport]' in '[serveraddr[:serverport]][@[bindaddr]:[bindport]]'

Jean-Paul Saman jpsaman at videolan.org
Fri Oct 28 17:47:35 CEST 2016


Filip,

I see you are already addressing the atoi() checks. Thus I'll wait to
include that in my patch series.
The other issue ipv6-bracket-check has been addressed.

>From 5d0298b9983247cc9f2f2ebca538c466b0fdf718 Mon Sep 17 00:00:00 2001
From: Jean-Paul Saman <jpsaman at videolan.org>
Date: Fri, 21 Oct 2016 14:29:49 +0200
Subject: [PATCH 1/3] vlc_url: parse '@[bindhost]:[bindport]' in
 '[serveraddr[:serverport]][@[bindaddr]:[bindport]]'

---
 include/vlc_url.h |   2 ++
 src/text/url.c    | 100
+++++++++++++++++++++++++++++++++++++++---------------
 2 files changed, 75 insertions(+), 27 deletions(-)

diff --git a/include/vlc_url.h b/include/vlc_url.h
index 5a20c27..802227e 100644
--- a/include/vlc_url.h
+++ b/include/vlc_url.h
@@ -149,6 +149,8 @@ struct vlc_url_t
     char *psz_password;
     char *psz_host;
     unsigned i_port;
+    char *psz_bind_host;
+    unsigned i_bind_port;
     char *psz_path;
     char *psz_option;

diff --git a/src/text/url.c b/src/text/url.c
index 6116893..3a95bb9 100644
--- a/src/text/url.c
+++ b/src/text/url.c
@@ -400,6 +400,33 @@ static bool vlc_uri_path_validate(const char *str)
     return vlc_uri_component_validate(str, "/@:");
 }

+static char *vlc_uri_host_get(char *str, char **saveptr)
+{
+    char *host = NULL;
+    char *next;
+
+    if (*str == '[' && (next = strchr(str, ']')) != NULL)
+    {   /* Try IPv6 numeral within brackets */
+        *(next++) = '\0';
+        host = strdup(str + 1);
+
+        if (*next == ':')
+            next++;
+        else
+            next = NULL;
+    }
+    else
+    {
+        next = strchr(str, ':');
+        if (next != NULL)
+            *(next++) = '\0';
+
+        host = vlc_idna_to_ascii(vlc_uri_decode(str));
+    }
+    *saveptr = next;
+    return host;
+}
+
 int vlc_UrlParse(vlc_url_t *restrict url, const char *str)
 {
     url->psz_protocol = NULL;
@@ -407,6 +434,8 @@ int vlc_UrlParse(vlc_url_t *restrict url, const char
*str)
     url->psz_password = NULL;
     url->psz_host = NULL;
     url->i_port = 0;
+    url->psz_bind_host = NULL;
+    url->i_bind_port = 0;
     url->psz_path = NULL;
     url->psz_option = NULL;
     url->psz_buffer = NULL;
@@ -473,45 +502,61 @@ int vlc_UrlParse(vlc_url_t *restrict url, const char
*str)
         /*else
             url->psz_path = "/";*/

-        /* User name */
-        next = strrchr(cur, '@');
-        if (next != NULL)
+        if (url->psz_protocol && (strcmp(url->psz_protocol, "udp") == 0))
         {
-            *(next++) = '\0';
-            url->psz_username = cur;
-            cur = next;
-
-            /* Password (obsolete) */
-            next = strchr(url->psz_username, ':');
+            /*
+             * Parse udp syntax:
+             * [serveraddr[:serverport]][@[bindaddr]:[bindport]]
+             */
+            next = strchr(cur, '@');
             if (next != NULL)
             {
                 *(next++) = '\0';
-                url->psz_password = next;
-                vlc_uri_decode(url->psz_password);
+                char *psz_bindhost = strdup(next);
+                url->psz_bind_host = vlc_uri_host_get(psz_bindhost, &next);
+
+                if (url->psz_bind_host == NULL)
+                    ret = -1;
+                else
+                    if (!vlc_uri_host_validate(url->psz_bind_host))
+                    {
+                        free(url->psz_bind_host);
+                        url->psz_bind_host = NULL;
+                        errno = EINVAL;
+                        ret = -1;
+                    }
+                /* Port number */
+                if (next != NULL)
+                    url->i_bind_port = atoi(next);
+
+                free(psz_bindhost);
             }
-            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);
-
-            if (*next == ':')
-                next++;
-            else
-                next = NULL;
         }
         else
         {
-            next = strchr(cur, ':');
+            /* User name */
+            next = strrchr(cur, '@');
             if (next != NULL)
+            {
                 *(next++) = '\0';
-
-            url->psz_host = vlc_idna_to_ascii(vlc_uri_decode(cur));
+                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);
+            }
         }

+        /* Host name */
+        url->psz_host = vlc_uri_host_get(cur, &next);
+
         if (url->psz_host == NULL)
             ret = -1;
         else
@@ -547,6 +592,7 @@ int vlc_UrlParse(vlc_url_t *restrict url, const char
*str)

 void vlc_UrlClean (vlc_url_t *restrict url)
 {
+    free (url->psz_bind_host);
     free (url->psz_host);
     free (url->psz_buffer);
 }
-- 
2.7.4
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/vlc-devel/attachments/20161028/d51fe73b/attachment.html>


More information about the vlc-devel mailing list