Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 27 Nov 2018 10:45:14 +0000 (UTC)
From:      =?UTF-8?Q?Dag-Erling_Sm=c3=b8rgrav?= <des@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r341013 - head/lib/libfetch
Message-ID:  <201811271045.wARAjEbp050427@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: des
Date: Tue Nov 27 10:45:14 2018
New Revision: 341013
URL: https://svnweb.freebsd.org/changeset/base/341013

Log:
  Improve URL parsing.  In particular, convert scheme and host to lowercase.
  
  MFC after:	1 week

Modified:
  head/lib/libfetch/common.c
  head/lib/libfetch/fetch.c
  head/lib/libfetch/ftp.c

Modified: head/lib/libfetch/common.c
==============================================================================
--- head/lib/libfetch/common.c	Tue Nov 27 10:31:29 2018	(r341012)
+++ head/lib/libfetch/common.c	Tue Nov 27 10:45:14 2018	(r341013)
@@ -189,9 +189,9 @@ fetch_default_port(const char *scheme)
 
 	if ((se = getservbyname(scheme, "tcp")) != NULL)
 		return (ntohs(se->s_port));
-	if (strcasecmp(scheme, SCHEME_FTP) == 0)
+	if (strcmp(scheme, SCHEME_FTP) == 0)
 		return (FTP_DEFAULT_PORT);
-	if (strcasecmp(scheme, SCHEME_HTTP) == 0)
+	if (strcmp(scheme, SCHEME_HTTP) == 0)
 		return (HTTP_DEFAULT_PORT);
 	return (0);
 }
@@ -202,9 +202,9 @@ fetch_default_port(const char *scheme)
 int
 fetch_default_proxy_port(const char *scheme)
 {
-	if (strcasecmp(scheme, SCHEME_FTP) == 0)
+	if (strcmp(scheme, SCHEME_FTP) == 0)
 		return (FTP_DEFAULT_PROXY_PORT);
-	if (strcasecmp(scheme, SCHEME_HTTP) == 0)
+	if (strcmp(scheme, SCHEME_HTTP) == 0)
 		return (HTTP_DEFAULT_PROXY_PORT);
 	return (0);
 }

Modified: head/lib/libfetch/fetch.c
==============================================================================
--- head/lib/libfetch/fetch.c	Tue Nov 27 10:31:29 2018	(r341012)
+++ head/lib/libfetch/fetch.c	Tue Nov 27 10:45:14 2018	(r341013)
@@ -32,8 +32,10 @@
 __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
-#include <sys/errno.h>
 
+#include <netinet/in.h>
+
+#include <errno.h>
 #include <ctype.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -81,13 +83,13 @@ fetchXGet(struct url *URL, struct url_stat *us, const 
 		us->size = -1;
 		us->atime = us->mtime = 0;
 	}
-	if (strcasecmp(URL->scheme, SCHEME_FILE) == 0)
+	if (strcmp(URL->scheme, SCHEME_FILE) == 0)
 		return (fetchXGetFile(URL, us, flags));
-	else if (strcasecmp(URL->scheme, SCHEME_FTP) == 0)
+	else if (strcmp(URL->scheme, SCHEME_FTP) == 0)
 		return (fetchXGetFTP(URL, us, flags));
-	else if (strcasecmp(URL->scheme, SCHEME_HTTP) == 0)
+	else if (strcmp(URL->scheme, SCHEME_HTTP) == 0)
 		return (fetchXGetHTTP(URL, us, flags));
-	else if (strcasecmp(URL->scheme, SCHEME_HTTPS) == 0)
+	else if (strcmp(URL->scheme, SCHEME_HTTPS) == 0)
 		return (fetchXGetHTTP(URL, us, flags));
 	url_seterr(URL_BAD_SCHEME);
 	return (NULL);
@@ -111,13 +113,13 @@ FILE *
 fetchPut(struct url *URL, const char *flags)
 {
 
-	if (strcasecmp(URL->scheme, SCHEME_FILE) == 0)
+	if (strcmp(URL->scheme, SCHEME_FILE) == 0)
 		return (fetchPutFile(URL, flags));
-	else if (strcasecmp(URL->scheme, SCHEME_FTP) == 0)
+	else if (strcmp(URL->scheme, SCHEME_FTP) == 0)
 		return (fetchPutFTP(URL, flags));
-	else if (strcasecmp(URL->scheme, SCHEME_HTTP) == 0)
+	else if (strcmp(URL->scheme, SCHEME_HTTP) == 0)
 		return (fetchPutHTTP(URL, flags));
-	else if (strcasecmp(URL->scheme, SCHEME_HTTPS) == 0)
+	else if (strcmp(URL->scheme, SCHEME_HTTPS) == 0)
 		return (fetchPutHTTP(URL, flags));
 	url_seterr(URL_BAD_SCHEME);
 	return (NULL);
@@ -135,13 +137,13 @@ fetchStat(struct url *URL, struct url_stat *us, const 
 		us->size = -1;
 		us->atime = us->mtime = 0;
 	}
-	if (strcasecmp(URL->scheme, SCHEME_FILE) == 0)
+	if (strcmp(URL->scheme, SCHEME_FILE) == 0)
 		return (fetchStatFile(URL, us, flags));
-	else if (strcasecmp(URL->scheme, SCHEME_FTP) == 0)
+	else if (strcmp(URL->scheme, SCHEME_FTP) == 0)
 		return (fetchStatFTP(URL, us, flags));
-	else if (strcasecmp(URL->scheme, SCHEME_HTTP) == 0)
+	else if (strcmp(URL->scheme, SCHEME_HTTP) == 0)
 		return (fetchStatHTTP(URL, us, flags));
-	else if (strcasecmp(URL->scheme, SCHEME_HTTPS) == 0)
+	else if (strcmp(URL->scheme, SCHEME_HTTPS) == 0)
 		return (fetchStatHTTP(URL, us, flags));
 	url_seterr(URL_BAD_SCHEME);
 	return (-1);
@@ -155,13 +157,13 @@ struct url_ent *
 fetchList(struct url *URL, const char *flags)
 {
 
-	if (strcasecmp(URL->scheme, SCHEME_FILE) == 0)
+	if (strcmp(URL->scheme, SCHEME_FILE) == 0)
 		return (fetchListFile(URL, flags));
-	else if (strcasecmp(URL->scheme, SCHEME_FTP) == 0)
+	else if (strcmp(URL->scheme, SCHEME_FTP) == 0)
 		return (fetchListFTP(URL, flags));
-	else if (strcasecmp(URL->scheme, SCHEME_HTTP) == 0)
+	else if (strcmp(URL->scheme, SCHEME_HTTP) == 0)
 		return (fetchListHTTP(URL, flags));
-	else if (strcasecmp(URL->scheme, SCHEME_HTTPS) == 0)
+	else if (strcmp(URL->scheme, SCHEME_HTTPS) == 0)
 		return (fetchListHTTP(URL, flags));
 	url_seterr(URL_BAD_SCHEME);
 	return (NULL);
@@ -345,7 +347,7 @@ fetchParseURL(const char *URL)
 	char *doc;
 	const char *p, *q;
 	struct url *u;
-	int i;
+	int i, n;
 
 	/* allocate struct url */
 	if ((u = calloc(1, sizeof(*u))) == NULL) {
@@ -356,8 +358,10 @@ fetchParseURL(const char *URL)
 
 	/* scheme name */
 	if ((p = strstr(URL, ":/"))) {
-		snprintf(u->scheme, URL_SCHEMELEN+1,
-		    "%.*s", (int)(p - URL), URL);
+                if (p - URL > URL_SCHEMELEN)
+                        goto ouch;
+                for (i = 0; URL + i < p; i++)
+                        u->scheme[i] = tolower((unsigned char)URL[i]);
 		URL = ++p;
 		/*
 		 * Only one slash: no host, leave slash as part of document
@@ -388,28 +392,37 @@ fetchParseURL(const char *URL)
 	}
 
 	/* hostname */
-	if (*p == '[' && (q = strchr(p + 1, ']')) != NULL &&
-	    (*++q == '\0' || *q == '/' || *q == ':')) {
-		if ((i = q - p) > MAXHOSTNAMELEN)
-			i = MAXHOSTNAMELEN;
-		strncpy(u->host, p, i);
-		p = q;
+	if (*p == '[') {
+		q = p + 1 + strspn(p + 1, ":0123456789ABCDEFabcdef");
+		if (*q++ != ']')
+			goto ouch;
 	} else {
-		for (i = 0; *p && (*p != '/') && (*p != ':'); p++)
-			if (i < MAXHOSTNAMELEN)
-				u->host[i++] = *p;
+		/* valid characters in a DNS name */
+		q = p + strspn(p, "-." "0123456789"
+		    "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "_"
+		    "abcdefghijklmnopqrstuvwxyz");
 	}
+	if ((*q != '\0' && *q != '/' && *q != ':') || q - p > MAXHOSTNAMELEN)
+		goto ouch;
+	for (i = 0; p + i < q; i++)
+		u->host[i] = tolower((unsigned char)p[i]);
+	u->host[i] = '\0';
+	p = q;
 
 	/* port */
 	if (*p == ':') {
-		for (q = ++p; *q && (*q != '/'); q++)
-			if (isdigit((unsigned char)*q))
-				u->port = u->port * 10 + (*q - '0');
-			else {
+		for (n = 0, q = ++p; *q && (*q != '/'); q++) {
+			if (*q >= '0' && *q <= '9' && n < INT_MAX / 10) {
+				n = n * 10 + (*q - '0');
+			} else {
 				/* invalid port */
 				url_seterr(URL_BAD_PORT);
 				goto ouch;
 			}
+		}
+		if (n < 1 || n > IPPORT_MAX)
+			goto ouch;
+		u->port = n;
 		p = q;
 	}
 
@@ -418,8 +431,8 @@ nohost:
 	if (!*p)
 		p = "/";
 
-	if (strcasecmp(u->scheme, SCHEME_HTTP) == 0 ||
-	    strcasecmp(u->scheme, SCHEME_HTTPS) == 0) {
+	if (strcmp(u->scheme, SCHEME_HTTP) == 0 ||
+	    strcmp(u->scheme, SCHEME_HTTPS) == 0) {
 		const char hexnums[] = "0123456789abcdef";
 
 		/* percent-escape whitespace. */

Modified: head/lib/libfetch/ftp.c
==============================================================================
--- head/lib/libfetch/ftp.c	Tue Nov 27 10:31:29 2018	(r341012)
+++ head/lib/libfetch/ftp.c	Tue Nov 27 10:45:14 2018	(r341013)
@@ -1085,8 +1085,8 @@ ftp_get_proxy(struct url * url, const char *flags)
 		}
 		if (!purl->port)
 			purl->port = fetch_default_proxy_port(purl->scheme);
-		if (strcasecmp(purl->scheme, SCHEME_FTP) == 0 ||
-		    strcasecmp(purl->scheme, SCHEME_HTTP) == 0)
+		if (strcmp(purl->scheme, SCHEME_FTP) == 0 ||
+		    strcmp(purl->scheme, SCHEME_HTTP) == 0)
 			return (purl);
 		fetchFreeURL(purl);
 	}
@@ -1104,8 +1104,8 @@ ftp_request(struct url *url, const char *op, struct ur
 	int oflag;
 
 	/* check if we should use HTTP instead */
-	if (purl && (strcasecmp(purl->scheme, SCHEME_HTTP) == 0 ||
-	    strcasecmp(purl->scheme, SCHEME_HTTPS) == 0)) {
+	if (purl && (strcmp(purl->scheme, SCHEME_HTTP) == 0 ||
+	    strcmp(purl->scheme, SCHEME_HTTPS) == 0)) {
 		if (strcmp(op, "STAT") == 0)
 			return (http_request(url, "HEAD", us, purl, flags));
 		else if (strcmp(op, "RETR") == 0)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201811271045.wARAjEbp050427>