git: fe95c6e2aa0c - stable/12 - Improve URL parsing. In particular, convert scheme and host to lowercase.
Renato Botelho
garga at FreeBSD.org
Wed Apr 28 19:38:31 UTC 2021
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 <des at FreeBSD.org>
AuthorDate: 2018-11-27 10:45:14 +0000
Commit: Renato Botelho <garga at FreeBSD.org>
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 <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 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)
More information about the dev-commits-src-all
mailing list