From 632f7df653ae7636a89a2b6d9b7db88089f80129 Mon Sep 17 00:00:00 2001 From: Rob Kendrick Date: Sat, 4 Dec 2010 16:35:48 +0000 Subject: More IPv6 compatibility work, added hack to cope with incorrect calls to url_host_is_ip_address while we fix the callers. svn path=/trunk/netsurf/; revision=10968 --- utils/url.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 59 insertions(+), 7 deletions(-) (limited to 'utils/url.c') diff --git a/utils/url.c b/utils/url.c index d50026bb1..c1dba2f5b 100644 --- a/utils/url.c +++ b/utils/url.c @@ -89,20 +89,65 @@ void url_init(void) bool url_host_is_ip_address(const char *host) { struct in_addr ipv4; + size_t z = strlen(host); + const char *sane_host; + const char *slash; #ifndef NO_IPV6 struct in6_addr ipv6; + char ipv6_addr[64]; #endif - if (strspn(host, "0123456789abcdefABCDEF[].:") < strlen(host)) - return false; + /* FIXME TODO: Some parts of urldb.c (and perhaps other parts of + * NetSurf) make confusions between hosts and "prefixes", we can + * sometimes be erroneously passed more than just a host. Sometimes + * we may be passed trailing slashes, or even whole path segments. + * A specific criminal in this class is urldb_iterate_partial, which + * takes a prefix to search for, but passes that prefix to functions + * that expect only hosts. + * + * For the time being, we will accept such calls; we check if there + * is a / in the host parameter, and if there is, we take a copy and + * replace the / with a \0. This is not a permanent solution; we + * should search through NetSurf and find all the callers that are + * in error and fix them. When doing this task, it might be wise + * to replace the hideousness below with code that doesn't have to do + * this, and add assert(strchr(host, '/') == NULL); somewhere. + * -- rjek - 2010-11-04 + */ + + slash = index(host, '/'); + if (slash == NULL) { + sane_host = host; + } else { + char *c = strdup(host); + c[slash - host] = '\0'; + sane_host = c; + LOG(("WARNING: called with non-host '%s'", + host)); + } + + if (strspn(sane_host, "0123456789abcdefABCDEF[].:") < z) + goto out_false; - if (inet_aton(host, &ipv4) != 0) - return true; + if (inet_aton(sane_host, &ipv4) != 0) + goto out_true; #ifndef NO_IPV6 - if (inet_pton(AF_INET6, host, &ipv6) == 1) - return true; + if (sane_host[0] != '[' || sane_host[z] != ']') + goto out_false; + + strncpy(ipv6_addr, sane_host + 1, sizeof(ipv6_addr)); + ipv6_addr[z - 1] = '\0'; + + if (inet_pton(AF_INET6, ipv6_addr, &ipv6) == 1) + goto out_true; #endif +out_false: + if (slash != NULL) free((void *)sane_host); return false; + +out_true: + if (slash != NULL) free((void *)sane_host); + return true; } /** @@ -513,7 +558,14 @@ url_func_result url_host(const char *url, char **result) } host_start = strchr(components.authority, '@'); host_start = host_start ? host_start + 1 : components.authority; - host_end = strchr(host_start, ':'); + + /* skip over an IPv6 address if there is one */ + if (host_start[0] == '[') { + host_end = strchr(host_start, ']') + 1; + } else { + host_end = strchr(host_start, ':'); + } + if (!host_end) host_end = components.authority + strlen(components.authority); -- cgit v1.2.3