BUG/MINOR: tools: url2sa reads ipv4 too far

The url2sa implementation is inconsitent when parsing an IPv4, indeed
url2sa() takes a <ulen> as a parameter where the call to url2ipv4() takes
a null terminated string. Which means url2ipv4 could try to read more
that it is supposed to.

This function is only used from a buffer so it never reach a unallocated
space. It can only cause an issue when used from the httpclient which
uses it with an ist.

This patch fixes the issue by copying everything in the trash and
null-terminated it.

Must be backported in all supported version.

(cherry picked from commit 8a91374487e13cf139ab36e483163a21ebdc6f4e)
Signed-off-by: William Lallemand <wlallemand@haproxy.org>
(cherry picked from commit 597e436053258d71e57381e14e1fae10220630bc)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
diff --git a/src/tools.c b/src/tools.c
index d14286c..bdf78ff 100644
--- a/src/tools.c
+++ b/src/tools.c
@@ -1673,12 +1673,20 @@
 		return end - url;
 	}
 	else {
+		/* we need to copy the string into the trash because url2ipv4
+		 * needs a \0 at the end of the string */
+		if (trash.size < ulen)
+			return -1;
+
+		memcpy(trash.area, curr, ulen - (curr - url));
+		trash.area[ulen - (curr - url)] = '\0';
+
 		/* We are looking for IP address. If you want to parse and
 		 * resolve hostname found in url, you can use str2sa_range(), but
 		 * be warned this can slow down global daemon performances
 		 * while handling lagging dns responses.
 		 */
-		ret = url2ipv4(curr, &((struct sockaddr_in *)addr)->sin_addr);
+		ret = url2ipv4(trash.area, &((struct sockaddr_in *)addr)->sin_addr);
 		if (ret) {
 			/* Update out. */
 			if (out) {
@@ -1686,7 +1694,9 @@
 				out->host_len = ret;
 			}
 
-			curr += ret;
+			/* we need to assign again curr and end from the trash */
+			url = trash.area;
+			curr = trash.area + ret;
 
 			/* Decode port. */
 			if (*curr == ':') {