From owner-dev-commits-src-all@freebsd.org Wed Apr 28 19:38:31 2021 Return-Path: Delivered-To: dev-commits-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 474A75FF18F; Wed, 28 Apr 2021 19:38:31 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4FVppH1Mqjz3HSm; Wed, 28 Apr 2021 19:38:31 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 2060113B51; Wed, 28 Apr 2021 19:38:31 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 13SJcVQ0064575; Wed, 28 Apr 2021 19:38:31 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 13SJcVlr064574; Wed, 28 Apr 2021 19:38:31 GMT (envelope-from git) Date: Wed, 28 Apr 2021 19:38:31 GMT Message-Id: <202104281938.13SJcVlr064574@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Renato Botelho Subject: git: fe95c6e2aa0c - stable/12 - Improve URL parsing. In particular, convert scheme and host to lowercase. MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: garga X-Git-Repository: src X-Git-Refname: refs/heads/stable/12 X-Git-Reftype: branch X-Git-Commit: fe95c6e2aa0caf36422294ef69124613a8a294fc Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-all@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commit messages for all branches of the src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 28 Apr 2021 19:38:31 -0000 The branch stable/12 has been updated by garga (ports committer): URL: https://cgit.FreeBSD.org/src/commit/?id=fe95c6e2aa0caf36422294ef69124613a8a294fc commit fe95c6e2aa0caf36422294ef69124613a8a294fc Author: Dag-Erling Smørgrav AuthorDate: 2018-11-27 10:45:14 +0000 Commit: Renato Botelho CommitDate: 2021-04-28 19:31:11 +0000 Improve URL parsing. In particular, convert scheme and host to lowercase. MFC after: 1 week Approved by:▸ kp Sponsored by:▸ Rubicon Communications, LLC ("Netgate") (cherry picked from commit 8d9de5b10a24bd2d79ed99f139c0ac28c09b15ca) --- lib/libfetch/common.c | 8 ++--- lib/libfetch/fetch.c | 83 +++++++++++++++++++++++++++++---------------------- lib/libfetch/ftp.c | 8 ++--- 3 files changed, 56 insertions(+), 43 deletions(-) diff --git a/lib/libfetch/common.c b/lib/libfetch/common.c index 74bc145f6873..80a63123abdb 100644 --- a/lib/libfetch/common.c +++ b/lib/libfetch/common.c @@ -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); } diff --git a/lib/libfetch/fetch.c b/lib/libfetch/fetch.c index fdbcd3301aa3..82a3c5e451a9 100644 --- a/lib/libfetch/fetch.c +++ b/lib/libfetch/fetch.c @@ -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 char *flags) 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 char *flags) 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); @@ -350,7 +352,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) { @@ -361,8 +363,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 @@ -397,28 +401,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; } @@ -427,8 +440,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. */ diff --git a/lib/libfetch/ftp.c b/lib/libfetch/ftp.c index 18fa673147d4..9a546f3fecad 100644 --- a/lib/libfetch/ftp.c +++ b/lib/libfetch/ftp.c @@ -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 url_stat *us, 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)