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)
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to