From 63533cbde279ce91ed9e9c92d47b6297235d1d02 Mon Sep 17 00:00:00 2001
From: Daniel Gustafsson <daniel@yesql.se>
Date: Tue, 11 Dec 2018 15:02:19 +0100
Subject: [PATCH] urlapi: fix portnumber parsing for ipv6 zone index

An IPv6 URL which contains a zone index includes a '%%25<zode id>'
string before the ending ']' bracket. The parsing logic wasn't set
up to cope with the zone index however, resulting in a malformed url
error being returned. Fix by breaking the parsing into two stages
to correctly handle the zone index.

Closes #3355
Closes #3319
Reported-by: tonystz on Github
Reviewed-by: Daniel Stenberg <daniel@haxx.se>
Reviewed-by: Marcel Raad <Marcel.Raad@teamviewer.com>
---
 lib/urlapi.c | 26 ++++++++++++++++++++------
 1 file changed, 20 insertions(+), 6 deletions(-)

diff --git a/lib/urlapi.c b/lib/urlapi.c
index be9958cd8..21942ebad 100644
--- a/lib/urlapi.c
+++ b/lib/urlapi.c
@@ -490,16 +490,30 @@ static CURLUcode parse_hostname_login(struct Curl_URL *u,
 
 static CURLUcode parse_port(struct Curl_URL *u, char *hostname)
 {
-  char *portptr;
+  char *portptr = NULL;
   char endbracket;
   int len;
 
-  if((1 == sscanf(hostname, "[%*45[0123456789abcdefABCDEF:.%%]%c%n",
-                  &endbracket, &len)) &&
-     (']' == endbracket)) {
+  /*
+   * Find the end of an IPv6 address, either on the ']' ending bracket or
+   * a percent-encoded zone index.
+   */
+  if(1 == sscanf(hostname, "[%*45[0123456789abcdefABCDEF:.]%c%n",
+                 &endbracket, &len)) {
+    if(']' == endbracket)
+      portptr = &hostname[len];
+    else if('%' == endbracket) {
+      int zonelen = len;
+      if(1 == sscanf(hostname + zonelen, "25%*[^]]]%c%n", &endbracket, &len))
+        portptr = &hostname[--zonelen + len];
+      else
+        return CURLUE_MALFORMED_INPUT;
+    }
+    else
+      return CURLUE_MALFORMED_INPUT;
+
     /* this is a RFC2732-style specified IP-address */
-    portptr = &hostname[len];
-    if(*portptr) {
+    if(portptr && *portptr) {
       if(*portptr != ':')
         return CURLUE_MALFORMED_INPUT;
     }
-- 
2.40.0