mirror of
https://github.com/netsurf-browser/netsurf
synced 2025-02-24 02:14:11 +03:00
Fix url_host_is_ip_address() when encountering blatently invalid IPv4 addresses (which inet_aton fails to notice).
Also fix a number of insidious buffer overflows. svn path=/trunk/netsurf/; revision=11293
This commit is contained in:
parent
b58dcc351f
commit
e65bdafbe3
37
utils/url.c
37
utils/url.c
@ -28,7 +28,6 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <strings.h>
|
|
||||||
#include <regex.h>
|
#include <regex.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
@ -91,7 +90,7 @@ void url_init(void)
|
|||||||
bool url_host_is_ip_address(const char *host)
|
bool url_host_is_ip_address(const char *host)
|
||||||
{
|
{
|
||||||
struct in_addr ipv4;
|
struct in_addr ipv4;
|
||||||
size_t z = strlen(host);
|
size_t host_len = strlen(host);
|
||||||
const char *sane_host;
|
const char *sane_host;
|
||||||
const char *slash;
|
const char *slash;
|
||||||
#ifndef NO_IPV6
|
#ifndef NO_IPV6
|
||||||
@ -116,28 +115,46 @@ bool url_host_is_ip_address(const char *host)
|
|||||||
* -- rjek - 2010-11-04
|
* -- rjek - 2010-11-04
|
||||||
*/
|
*/
|
||||||
|
|
||||||
slash = index(host, '/');
|
slash = strchr(host, '/');
|
||||||
if (slash == NULL) {
|
if (slash == NULL) {
|
||||||
sane_host = host;
|
sane_host = host;
|
||||||
} else {
|
} else {
|
||||||
char *c = strdup(host);
|
char *c = strdup(host);
|
||||||
c[slash - host] = '\0';
|
c[slash - host] = '\0';
|
||||||
sane_host = c;
|
sane_host = c;
|
||||||
LOG(("WARNING: called with non-host '%s'",
|
host_len = slash - host - 1;
|
||||||
host));
|
LOG(("WARNING: called with non-host '%s'", host));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strspn(sane_host, "0123456789abcdefABCDEF[].:") < z)
|
if (strspn(sane_host, "0123456789abcdefABCDEF[].:") < host_len)
|
||||||
goto out_false;
|
goto out_false;
|
||||||
|
|
||||||
if (inet_aton(sane_host, &ipv4) != 0)
|
if (inet_aton(sane_host, &ipv4) != 0) {
|
||||||
goto out_true;
|
/* This can only be a sane IPv4 address if it contains 3 dots.
|
||||||
|
* Helpfully, inet_aton is happy to treat "a", "a.b", "a.b.c",
|
||||||
|
* and "a.b.c.d" as valid IPv4 address strings where we only
|
||||||
|
* support the full, dotted-quad, form.
|
||||||
|
*/
|
||||||
|
int num_dots = 0;
|
||||||
|
size_t index;
|
||||||
|
|
||||||
|
for (index = 0; index < host_len; index++) {
|
||||||
|
if (sane_host[index] == '.')
|
||||||
|
num_dots++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (num_dots == 3)
|
||||||
|
goto out_true;
|
||||||
|
else
|
||||||
|
goto out_false;
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef NO_IPV6
|
#ifndef NO_IPV6
|
||||||
if (sane_host[0] != '[' || sane_host[z] != ']')
|
if (sane_host[0] != '[' || sane_host[host_len] != ']')
|
||||||
goto out_false;
|
goto out_false;
|
||||||
|
|
||||||
strncpy(ipv6_addr, sane_host + 1, sizeof(ipv6_addr));
|
strncpy(ipv6_addr, sane_host + 1, sizeof(ipv6_addr));
|
||||||
ipv6_addr[z - 1] = '\0';
|
ipv6_addr[sizeof(ipv6_addr) - 1] = '\0';
|
||||||
|
|
||||||
if (inet_pton(AF_INET6, ipv6_addr, &ipv6) == 1)
|
if (inet_pton(AF_INET6, ipv6_addr, &ipv6) == 1)
|
||||||
goto out_true;
|
goto out_true;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user