From owner-svn-src-head@freebsd.org Tue Nov 27 10:45:15 2018 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 8D54B11455A1; Tue, 27 Nov 2018 10:45:15 +0000 (UTC) (envelope-from des@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 30649710A1; Tue, 27 Nov 2018 10:45:15 +0000 (UTC) (envelope-from des@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 10CCD1A297; Tue, 27 Nov 2018 10:45:15 +0000 (UTC) (envelope-from des@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id wARAjEFk050430; Tue, 27 Nov 2018 10:45:14 GMT (envelope-from des@FreeBSD.org) Received: (from des@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id wARAjEbp050427; Tue, 27 Nov 2018 10:45:14 GMT (envelope-from des@FreeBSD.org) Message-Id: <201811271045.wARAjEbp050427@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: des set sender to des@FreeBSD.org using -f From: =?UTF-8?Q?Dag-Erling_Sm=c3=b8rgrav?= Date: Tue, 27 Nov 2018 10:45:14 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r341013 - head/lib/libfetch X-SVN-Group: head X-SVN-Commit-Author: des X-SVN-Commit-Paths: head/lib/libfetch X-SVN-Commit-Revision: 341013 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: 30649710A1 X-Spamd-Result: default: False [1.79 / 15.00]; local_wl_from(0.00)[FreeBSD.org]; NEURAL_SPAM_LONG(0.51)[0.511,0]; NEURAL_SPAM_SHORT(0.60)[0.595,0]; NEURAL_SPAM_MEDIUM(0.69)[0.687,0]; ASN(0.00)[asn:11403, ipnet:2610:1c1:1::/48, country:US] X-Rspamd-Server: mx1.freebsd.org X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 27 Nov 2018 10:45:15 -0000 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 -#include +#include + +#include #include #include #include @@ -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)