diff options
author | Daniel Stenberg <daniel@haxx.se> | 2020-06-18 13:27:59 +0200 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2020-06-18 16:43:06 +0200 |
commit | fa4fbc533f6ce7e76fc005972a3100ef2a26cc6c (patch) | |
tree | e3382263a94f33691102e8ae6aa9fcc40ab6c00f /src | |
parent | c888e3f6cee3ee28bf238184605b7516b00db737 (diff) | |
download | curl-fa4fbc533f6ce7e76fc005972a3100ef2a26cc6c.tar.gz |
urlglob: treat literal IPv6 addresses with zone IDs as a host name
... and not as a "glob". Now done by passing the supposed host to the
URL parser which supposedly will do a better job at identifying "real"
numerical IPv6 addresses.
Reported-by: puckipedia on github
Fixes #5576
Closes #5579
Diffstat (limited to 'src')
-rw-r--r-- | src/tool_urlglob.c | 47 |
1 files changed, 27 insertions, 20 deletions
diff --git a/src/tool_urlglob.c b/src/tool_urlglob.c index 32fd5d82a..430ca88ba 100644 --- a/src/tool_urlglob.c +++ b/src/tool_urlglob.c @@ -319,6 +319,8 @@ static CURLcode glob_range(struct URLGlob *glob, char **patternp, return CURLE_OK; } +#define MAX_IP6LEN 128 + static bool peek_ipv6(const char *str, size_t *skip) { /* @@ -326,27 +328,32 @@ static bool peek_ipv6(const char *str, size_t *skip) * - Valid globs contain a hyphen and <= 1 colon. * - IPv6 literals contain no hyphens and >= 2 colons. */ - size_t i = 0; - size_t colons = 0; - if(str[i++] != '[') { + char hostname[MAX_IP6LEN]; + CURLU *u; + char *endbr = strchr(str, ']'); + size_t hlen; + CURLUcode rc; + if(!endbr) return FALSE; - } - for(;;) { - const char c = str[i++]; - if(ISALNUM(c) || c == '.' || c == '%') { - /* ok */ - } - else if(c == ':') { - colons++; - } - else if(c == ']') { - *skip = i; - return colons >= 2 ? TRUE : FALSE; - } - else { - return FALSE; - } - } + + hlen = endbr - str + 1; + if(hlen >= MAX_IP6LEN) + return FALSE; + + u = curl_url(); + if(!u) + return FALSE; + + memcpy(hostname, str, hlen); + hostname[hlen] = 0; + + /* ask to "guess scheme" as then it works without a https:// prefix */ + rc = curl_url_set(u, CURLUPART_URL, hostname, CURLU_GUESS_SCHEME); + + curl_url_cleanup(u); + if(!rc) + *skip = hlen; + return rc ? FALSE : TRUE; } static CURLcode glob_parse(struct URLGlob *glob, char *pattern, |