]> granicus.if.org Git - neomutt/commitdiff
Allow IPv6 literal addresses in URLs. (closes #3681)
authorKevin McCarthy <kevin@8t8.us>
Sat, 15 Oct 2016 21:45:55 +0000 (14:45 -0700)
committerKevin McCarthy <kevin@8t8.us>
Sat, 15 Oct 2016 21:45:55 +0000 (14:45 -0700)
RFCs 2732 and 3986 specify a literal IPv6 address be surrounded by
"[]".

This patch removes the "[]" delimiters when parsing the URL, but adds
them back in url_ciss_tostring() if the host name contains a ':'.

Thanks to Evgeni Golov for the original patch.

url.c

diff --git a/url.c b/url.c
index 61742d0193786c1c04c85c258dfd20f66ed677b3..f380893803bfe04aa9e4516b4079a10d5f2a3e04 100644 (file)
--- a/url.c
+++ b/url.c
@@ -143,7 +143,16 @@ static int ciss_parse_userhost (ciss_url_t *ciss, char *src)
     ciss->user = src;
     if (url_pct_decode (ciss->user) < 0)
       return -1;
-    t++;
+    src = t + 1;
+  }
+
+  /* IPv6 literal address.  It may contain colons, so set t to start
+   * the port scan after it.
+   */
+  if ((*src == '[') && (t = strchr (src, ']')))
+  {
+    src++;
+    *t++ = '\0';
   }
   else
     t = src;
@@ -159,7 +168,7 @@ static int ciss_parse_userhost (ciss_url_t *ciss, char *src)
   else
     ciss->port = 0;
 
-  ciss->host = t;
+  ciss->host = src;
   return url_pct_decode (ciss->host) >= 0 &&
     (!ciss->path || url_pct_decode (ciss->path) >= 0) ? 0 : -1;
 }
@@ -232,10 +241,17 @@ int url_ciss_tostring (ciss_url_t* ciss, char* dest, size_t len, int flags)
       len -= (l = strlen (dest)); dest += l;
     }
 
+    if (strchr (ciss->host, ':'))
+      snprintf (dest, len, "[%s]", ciss->host);
+    else
+      snprintf (dest, len, "%s", ciss->host);
+
+    len -= (l = strlen (dest)); dest += l;
+
     if (ciss->port)
-      snprintf (dest, len, "%s:%hu/", ciss->host, ciss->port);
+      snprintf (dest, len, ":%hu/", ciss->port);
     else
-      snprintf (dest, len, "%s/", ciss->host);
+      snprintf (dest, len, "/");
   }
 
   if (ciss->path)