1
0
mirror of https://github.com/moparisthebest/curl synced 2024-11-15 14:05:03 -05:00

url: convert the zone id from a IPv6 URL to correct scope id

Reported-by: GitYuanQu on github
Fixes #3902
Closes #3914
This commit is contained in:
Daniel Stenberg 2019-05-21 09:43:10 +02:00
parent 9406d93e77
commit 8fba2d6a6b
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2

View File

@ -2002,61 +2002,40 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
hostname = (char *)""; hostname = (char *)"";
if(hostname[0] == '[') { if(hostname[0] == '[') {
/* This looks like an IPv6 address literal. See if there is an address /* This looks like an IPv6 address literal. See if there is an address
scope. */ scope. */
char *percent = strchr(++hostname, '%'); char *zoneid;
size_t hlen;
uc = curl_url_get(uh, CURLUPART_ZONEID, &zoneid, 0);
conn->bits.ipv6_ip = TRUE; conn->bits.ipv6_ip = TRUE;
if(percent) {
unsigned int identifier_offset = 3; /* cut off the brackets! */
hostname++;
hlen = strlen(hostname);
hostname[hlen - 1] = 0;
if(!uc && zoneid) {
char *endp; char *endp;
unsigned long scope; unsigned long scope;
if(strncmp("%25", percent, 3) != 0) { scope = strtoul(zoneid, &endp, 10);
infof(data, if(!*endp && (scope < UINT_MAX)) {
"Please URL encode %% as %%25, see RFC 6874.\n"); /* A plain number, use it direcly as a scope id. */
identifier_offset = 1;
}
scope = strtoul(percent + identifier_offset, &endp, 10);
if(*endp == ']') {
/* The address scope was well formed. Knock it out of the
hostname. */
memmove(percent, endp, strlen(endp) + 1);
conn->scope_id = (unsigned int)scope; conn->scope_id = (unsigned int)scope;
} }
#ifdef HAVE_IF_NAMETOINDEX
else { else {
/* Zone identifier is not numeric */ /* Zone identifier is not numeric */
#if defined(HAVE_NET_IF_H) && defined(IFNAMSIZ) && defined(HAVE_IF_NAMETOINDEX)
char ifname[IFNAMSIZ + 2];
char *square_bracket;
unsigned int scopeidx = 0; unsigned int scopeidx = 0;
strncpy(ifname, percent + identifier_offset, IFNAMSIZ + 2); scopeidx = if_nametoindex(zoneid);
/* Ensure nullbyte termination */ if(!scopeidx)
ifname[IFNAMSIZ + 1] = '\0'; infof(data, "Invalid zoneid id: %s; %s\n", zoneid,
square_bracket = strchr(ifname, ']'); strerror(errno));
if(square_bracket) {
/* Remove ']' */
*square_bracket = '\0';
scopeidx = if_nametoindex(ifname);
if(scopeidx == 0) {
infof(data, "Invalid network interface: %s; %s\n", ifname,
strerror(errno));
}
}
if(scopeidx > 0) {
char *p = percent + identifier_offset + strlen(ifname);
/* Remove zone identifier from hostname */
memmove(percent, p, strlen(p) + 1);
conn->scope_id = scopeidx;
}
else else
#endif /* HAVE_NET_IF_H && IFNAMSIZ */ conn->scope_id = scopeidx;
infof(data, "Invalid IPv6 address format\n");
} }
#endif /* HAVE_IF_NAMETOINDEX */
free(zoneid);
} }
percent = strchr(hostname, ']');
if(percent)
/* terminate IPv6 numerical at end bracket */
*percent = 0;
} }
/* make sure the connect struct gets its own copy of the host name */ /* make sure the connect struct gets its own copy of the host name */