diff --git a/dlls/winhttp/net.c b/dlls/winhttp/net.c index 79e67890298..f362a8b554d 100644 --- a/dlls/winhttp/net.c +++ b/dlls/winhttp/net.c @@ -566,7 +566,7 @@ DWORD netconn_set_timeout( netconn_t *netconn, BOOL send, int value ) return ERROR_SUCCESS; } -BOOL netconn_resolve( WCHAR *hostnameW, INTERNET_PORT port, struct sockaddr_in *sa ) +BOOL netconn_resolve( WCHAR *hostnameW, INTERNET_PORT port, struct sockaddr *sa, socklen_t *sa_len ) { char *hostname; #ifdef HAVE_GETADDRINFO @@ -574,6 +574,7 @@ BOOL netconn_resolve( WCHAR *hostnameW, INTERNET_PORT port, struct sockaddr_in * int ret; #else struct hostent *he; + struct sockaddr_in *sin = (struct sockaddr_in *)sa; #endif if (!(hostname = strdupWA( hostnameW ))) return FALSE; @@ -589,10 +590,17 @@ BOOL netconn_resolve( WCHAR *hostnameW, INTERNET_PORT port, struct sockaddr_in * TRACE("failed to get address of %s (%s)\n", debugstr_w(hostnameW), gai_strerror(ret)); return FALSE; } + if (*sa_len < sizeof(struct sockaddr_in)) + { + WARN("address too small\n"); + freeaddrinfo( res ); + return FALSE; + } + *sa_len = sizeof(struct sockaddr_in); memset( sa, 0, sizeof(struct sockaddr_in) ); - memcpy( &sa->sin_addr, &((struct sockaddr_in *)res->ai_addr)->sin_addr, sizeof(struct in_addr) ); - sa->sin_family = res->ai_family; - sa->sin_port = htons( port ); + memcpy( &((struct sockaddr_in *)sa)->sin_addr, &((struct sockaddr_in *)res->ai_addr)->sin_addr, sizeof(struct in_addr) ); + ((struct sockaddr_in *)sa)->sin_family = res->ai_family; + ((struct sockaddr_in *)sa)->sin_port = htons( port ); freeaddrinfo( res ); #else @@ -606,10 +614,17 @@ BOOL netconn_resolve( WCHAR *hostnameW, INTERNET_PORT port, struct sockaddr_in * LeaveCriticalSection( &cs_gethostbyname ); return FALSE; } + if (*sa_len < sizeof(struct sockaddr_in)) + { + WARN("address too small\n"); + LeaveCriticalSection( &cs_gethostbyname ); + return FALSE; + } + *sa_len = sizeof(struct sockaddr_in); memset( sa, 0, sizeof(struct sockaddr_in) ); - memcpy( &sa->sin_addr, he->h_addr, he->h_length ); - sa->sin_family = he->h_addrtype; - sa->sin_port = htons( port ); + memcpy( &sin->sin_addr, he->h_addr, he->h_length ); + sin->sin_family = he->h_addrtype; + sin->sin_port = htons( port ); LeaveCriticalSection( &cs_gethostbyname ); #endif diff --git a/dlls/winhttp/request.c b/dlls/winhttp/request.c index ddfac13c449..f088c40855c 100644 --- a/dlls/winhttp/request.c +++ b/dlls/winhttp/request.c @@ -716,6 +716,7 @@ static BOOL open_connection( request_t *request ) char address[32]; WCHAR *addressW; INTERNET_PORT port; + socklen_t slen; if (netconn_connected( &request->netconn )) return TRUE; @@ -724,7 +725,8 @@ static BOOL open_connection( request_t *request ) send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_RESOLVING_NAME, connect->servername, strlenW(connect->servername) + 1 ); - if (!netconn_resolve( connect->servername, port, &connect->sockaddr )) return FALSE; + slen = sizeof(connect->sockaddr); + if (!netconn_resolve( connect->servername, port, (struct sockaddr *)&connect->sockaddr, &slen )) return FALSE; inet_ntop( connect->sockaddr.sin_family, &connect->sockaddr.sin_addr, address, sizeof(address) ); addressW = strdupAW( address ); diff --git a/dlls/winhttp/winhttp_private.h b/dlls/winhttp/winhttp_private.h index 823d0ae2047..750acf50aed 100644 --- a/dlls/winhttp/winhttp_private.h +++ b/dlls/winhttp/winhttp_private.h @@ -211,7 +211,7 @@ BOOL netconn_get_next_line( netconn_t *, char *, DWORD * ); BOOL netconn_init( netconn_t *, BOOL ); BOOL netconn_query_data_available( netconn_t *, DWORD * ); BOOL netconn_recv( netconn_t *, void *, size_t, int, int * ); -BOOL netconn_resolve( WCHAR *, INTERNET_PORT, struct sockaddr_in * ); +BOOL netconn_resolve( WCHAR *, INTERNET_PORT, struct sockaddr *, socklen_t * ); BOOL netconn_secure_connect( netconn_t * ); BOOL netconn_send( netconn_t *, const void *, size_t, int, int * ); DWORD netconn_set_timeout( netconn_t *, BOOL, int );