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:
parent
9406d93e77
commit
8fba2d6a6b
65
lib/url.c
65
lib/url.c
@ -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 */
|
||||||
|
Loading…
Reference in New Issue
Block a user