WPS UPnP: Clean up URL parser

Remove unnecessary second copy of the URL and too long memory
allocation. In addition, avoid use of strcpy() to keep static analyzers
happier.

Signed-hostap: Jouni Malinen <j@w1.fi>
This commit is contained in:
Jouni Malinen 2012-02-19 13:19:34 +02:00
parent 4a0d25f08a
commit 974c56ac24

View file

@ -305,15 +305,15 @@ static void subscr_addr_add_url(struct subscription *s, const char *url,
int alloc_len; int alloc_len;
char *scratch_mem = NULL; char *scratch_mem = NULL;
char *mem; char *mem;
char *domain_and_port; char *host;
char *delim; char *delim;
char *path; char *path;
char *domain;
int port = 80; /* port to send to (default is port 80) */ int port = 80; /* port to send to (default is port 80) */
struct addrinfo hints; struct addrinfo hints;
struct addrinfo *result = NULL; struct addrinfo *result = NULL;
struct addrinfo *rp; struct addrinfo *rp;
int rerr; int rerr;
size_t host_len, path_len;
/* url MUST begin with http: */ /* url MUST begin with http: */
if (url_len < 7 || os_strncasecmp(url, "http://", 7)) if (url_len < 7 || os_strncasecmp(url, "http://", 7))
@ -321,30 +321,24 @@ static void subscr_addr_add_url(struct subscription *s, const char *url,
url += 7; url += 7;
url_len -= 7; url_len -= 7;
/* allocate memory for the extra stuff we need */ /* Make a copy of the string to allow modification during parsing */
alloc_len = 2 * (url_len + 1); scratch_mem = os_malloc(url_len + 1);
scratch_mem = os_zalloc(alloc_len);
if (scratch_mem == NULL) if (scratch_mem == NULL)
goto fail; goto fail;
mem = scratch_mem; os_memcpy(scratch_mem, url, url_len);
os_strncpy(mem, url, url_len); scratch_mem[url_len] = '\0';
wpa_printf(MSG_DEBUG, "WPS UPnP: Adding URL '%s'", mem); wpa_printf(MSG_DEBUG, "WPS UPnP: Adding URL '%s'", scratch_mem);
domain_and_port = mem; host = scratch_mem;
mem += 1 + os_strlen(mem); path = os_strchr(host, '/');
delim = os_strchr(domain_and_port, '/'); if (path)
*path++ = '\0'; /* null terminate host */
/* Process and remove optional port component */
delim = os_strchr(host, ':');
if (delim) { if (delim) {
*delim++ = 0; /* null terminate domain and port */ *delim = '\0'; /* null terminate host name for now */
path = delim; if (isdigit(delim[1]))
} else { port = atol(delim + 1);
path = domain_and_port + os_strlen(domain_and_port);
}
domain = mem;
strcpy(domain, domain_and_port);
delim = os_strchr(domain, ':');
if (delim) {
*delim++ = 0; /* null terminate domain */
if (isdigit(*delim))
port = atol(delim);
} }
/* /*
@ -367,13 +361,21 @@ static void subscr_addr_add_url(struct subscription *s, const char *url,
hints.ai_flags = 0; hints.ai_flags = 0;
#endif #endif
hints.ai_protocol = 0; /* Any protocol? */ hints.ai_protocol = 0; /* Any protocol? */
rerr = getaddrinfo(domain, NULL /* fill in port ourselves */, rerr = getaddrinfo(host, NULL /* fill in port ourselves */,
&hints, &result); &hints, &result);
if (rerr) { if (rerr) {
wpa_printf(MSG_INFO, "WPS UPnP: Resolve error %d (%s) on: %s", wpa_printf(MSG_INFO, "WPS UPnP: Resolve error %d (%s) on: %s",
rerr, gai_strerror(rerr), domain); rerr, gai_strerror(rerr), host);
goto fail; goto fail;
} }
if (delim)
*delim = ':'; /* Restore port */
host_len = os_strlen(host);
path_len = path ? os_strlen(path) : 0;
alloc_len = host_len + 1 + 1 + path_len + 1;
for (rp = result; rp; rp = rp->ai_next) { for (rp = result; rp; rp = rp->ai_next) {
struct subscr_addr *a; struct subscr_addr *a;
@ -386,16 +388,16 @@ static void subscr_addr_add_url(struct subscription *s, const char *url,
a = os_zalloc(sizeof(*a) + alloc_len); a = os_zalloc(sizeof(*a) + alloc_len);
if (a == NULL) if (a == NULL)
continue; break;
mem = (void *) (a + 1); mem = (char *) (a + 1);
a->domain_and_port = mem; a->domain_and_port = mem;
strcpy(mem, domain_and_port); os_memcpy(mem, host, host_len);
mem += 1 + strlen(mem); mem += host_len + 1;
a->path = mem; a->path = mem;
if (path[0] != '/') if (path == NULL || path[0] != '/')
*mem++ = '/'; *mem++ = '/';
strcpy(mem, path); if (path)
mem += 1 + os_strlen(mem); os_memcpy(mem, path, path_len);
os_memcpy(&a->saddr, rp->ai_addr, sizeof(a->saddr)); os_memcpy(&a->saddr, rp->ai_addr, sizeof(a->saddr));
a->saddr.sin_port = htons(port); a->saddr.sin_port = htons(port);