diff --git a/evdns.c b/evdns.c index 1c30972e..166a0caf 100644 --- a/evdns.c +++ b/evdns.c @@ -2295,9 +2295,9 @@ int evdns_base_nameserver_ip_add(struct evdns_base *base, const char *ip_as_string) { struct sockaddr_storage ss; struct sockaddr *sa; - int len; + int len = sizeof(ss); if (evutil_parse_sockaddr_port(ip_as_string, (struct sockaddr *)&ss, - sizeof(ss))) { + &len)) { log(EVDNS_LOG_WARN, "Unable to parse nameserver address %s", ip_as_string); return 4; @@ -2307,14 +2307,12 @@ evdns_base_nameserver_ip_add(struct evdns_base *base, const char *ip_as_string) struct sockaddr_in *sin = (struct sockaddr_in *)sa; if (sin->sin_port == 0) sin->sin_port = htons(53); - len = sizeof(struct sockaddr_in); } #ifdef AF_INET6 else if (sa->sa_family == AF_INET6) { struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa; if (sin6->sin6_port == 0) sin6->sin6_port = htons(53); - len = sizeof(struct sockaddr_in6); } #endif else diff --git a/evutil.c b/evutil.c index 38095592..6b4bb96d 100644 --- a/evutil.c +++ b/evutil.c @@ -582,7 +582,7 @@ evutil_inet_pton(int af, const char *src, void *dst) } int -evutil_parse_sockaddr_port(const char *ip_as_string, struct sockaddr *out, int outlen) +evutil_parse_sockaddr_port(const char *ip_as_string, struct sockaddr *out, int *outlen) { int port; char buf[128]; @@ -654,10 +654,11 @@ evutil_parse_sockaddr_port(const char *ip_as_string, struct sockaddr *out, int o sin6.sin6_port = htons(port); if (1 != evutil_inet_pton(AF_INET6, addr_part, &sin6.sin6_addr)) return -1; - if (sizeof(sin6) > outlen) + if (sizeof(sin6) > *outlen) return -1; - memset(out, 0, outlen); + memset(out, 0, *outlen); memcpy(out, &sin6, sizeof(sin6)); + *outlen = sizeof(sin6); return 0; } else { struct sockaddr_in sin; @@ -669,10 +670,11 @@ evutil_parse_sockaddr_port(const char *ip_as_string, struct sockaddr *out, int o sin.sin_port = htons(port); if (1 != evutil_inet_pton(AF_INET, addr_part, &sin.sin_addr)) return -1; - if (sizeof(sin) > outlen) + if (sizeof(sin) > *outlen) return -1; - memset(out, 0, outlen); + memset(out, 0, *outlen); memcpy(out, &sin, sizeof(sin)); + *outlen = sizeof(sin); return 0; } } diff --git a/include/event2/util.h b/include/event2/util.h index 6d331951..2e7ac810 100644 --- a/include/event2/util.h +++ b/include/event2/util.h @@ -262,12 +262,13 @@ struct sockaddr; @param str The string to parse. @param out A struct sockaddr to hold the result. This should probably be a struct sockaddr_storage. - @param outlen The number of bytes that 'out' can safely hold. + @param outlen A pointer to the number of bytes that that 'out' can safely + hold. Set to the number of bytes used in 'out' on sucess. @return -1 if the address is not well-formed, if the port is out of range, or if out is not large enough to hold the result. Otherwise returns 0 on success. */ -int evutil_parse_sockaddr_port(const char *str, struct sockaddr *out, int outlen); +int evutil_parse_sockaddr_port(const char *str, struct sockaddr *out, int *outlen); #ifdef __cplusplus diff --git a/test/regress_util.c b/test/regress_util.c index e78ee6a7..7e2bad71 100644 --- a/test/regress_util.c +++ b/test/regress_util.c @@ -220,8 +220,9 @@ regress_sockaddr_port_parse(void *ptr) for (i = 0; sa_port_ents[i].parse; ++i) { struct sa_port_ent *ent = &sa_port_ents[i]; + int len = sizeof(ss); memset(&ss, 0, sizeof(ss)); - r = evutil_parse_sockaddr_port(ent->parse, (struct sockaddr*)&ss, sizeof(ss)); + r = evutil_parse_sockaddr_port(ent->parse, (struct sockaddr*)&ss, &len); if (r < 0) { if (ent->sa_family) TT_FAIL(("Couldn't parse %s!", ent->parse)); @@ -239,11 +240,13 @@ regress_sockaddr_port_parse(void *ptr) sin.sin_family = AF_INET; sin.sin_port = htons(ent->port); r = evutil_inet_pton(AF_INET, ent->addr, &sin.sin_addr); - if (1 != r) { + if (1 != r) { TT_FAIL(("Couldn't parse ipv4 target %s.", ent->addr)); } else if (memcmp(&sin, &ss, sizeof(sin))) { TT_FAIL(("Parse for %s was not as expected.", ent->parse)); - } + } else if (len != sizeof(sin)) { + TT_FAIL(("Length for %s not as expected.",ent->parse)); + } } else { struct sockaddr_in6 sin6; memset(&sin6, 0, sizeof(sin6)); @@ -257,6 +260,8 @@ regress_sockaddr_port_parse(void *ptr) TT_FAIL(("Couldn't parse ipv6 target %s.", ent->addr)); } else if (memcmp(&sin6, &ss, sizeof(sin6))) { TT_FAIL(("Parse for %s was not as expected.", ent->parse)); + } else if (len != sizeof(sin6)) { + TT_FAIL(("Length for %s not as expected.",ent->parse)); } } }