Module: wine Branch: master Commit: b60cd6830848431e359196bb1d801e93d0952fdf URL: http://source.winehq.org/git/wine.git/?a=commit;h=b60cd6830848431e359196bb1d...
Author: Bruno Jesus bjesus@codeweavers.com Date: Thu Mar 2 22:21:44 2017 -0300
ws2_32: Fix WSAStringToAddress parsing for IPv6.
Signed-off-by: Bruno Jesus bjesus@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/ws2_32/socket.c | 36 ++++++++++++++++++------------------ dlls/ws2_32/tests/sock.c | 4 ---- 2 files changed, 18 insertions(+), 22 deletions(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 451c505..d13fbf4 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -8255,10 +8255,6 @@ INT WINAPI WSAStringToAddressA(LPSTR AddressString, ((LPSOCKADDR_IN)lpAddress)->sin_port = htons(atoi(ptrPort+1)); *ptrPort = '\0'; } - else - { - ((LPSOCKADDR_IN)lpAddress)->sin_port = 0; - }
if(inet_aton(workBuffer, &inetaddr) > 0) { @@ -8269,11 +8265,12 @@ INT WINAPI WSAStringToAddressA(LPSTR AddressString, res = WSAEINVAL;
break; - } case WS_AF_INET6: { struct in6_addr inetaddr; + char *ptrAddr = workBuffer; + /* If lpAddressLength is too small, tell caller the size we need */ if (*lpAddressLength < sizeof(SOCKADDR_IN6)) { @@ -8287,24 +8284,27 @@ INT WINAPI WSAStringToAddressA(LPSTR AddressString,
((LPSOCKADDR_IN6)lpAddress)->sin6_family = WS_AF_INET6;
- /* This one is a bit tricky. An IPv6 address contains colons, so the - * check from IPv4 doesn't work like that. However, IPv6 addresses that - * contain a port are written with braces like [fd12:3456:7890::1]:12345 - * so what we will do is to look for ']', check if the next char is a - * colon, and if it is, parse the port as in IPv4. */ + /* Valid IPv6 addresses can also be surrounded by [ ], and in this case + * a port number may follow after like in [fd12:3456:7890::1]:12345 + * We need to cut the brackets and find the port if any. */
- ptrPort = strchr(workBuffer, ']'); - if(ptrPort && *(++ptrPort) == ':') + if(*workBuffer == '[') { - ((LPSOCKADDR_IN6)lpAddress)->sin6_port = htons(atoi(ptrPort+1)); + ptrPort = strchr(workBuffer, ']'); + if (!ptrPort) + { + SetLastError(WSAEINVAL); + return SOCKET_ERROR; + } + + if (ptrPort[1] == ':') + ((LPSOCKADDR_IN6)lpAddress)->sin6_port = htons(atoi(ptrPort + 2)); + *ptrPort = '\0'; - } - else - { - ((LPSOCKADDR_IN6)lpAddress)->sin6_port = 0; + ptrAddr = workBuffer + 1; }
- if(inet_pton(AF_INET6, workBuffer, &inetaddr) > 0) + if(inet_pton(AF_INET6, ptrAddr, &inetaddr) > 0) { memcpy(&((LPSOCKADDR_IN6)lpAddress)->sin6_addr, &inetaddr, sizeof(struct in6_addr)); diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index bf90ce5..c77f43b 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -3426,7 +3426,6 @@ static void test_WSAStringToAddressA(void) ret = WSAStringToAddressA( address7, AF_INET6, NULL, (SOCKADDR*)&sockaddr6, &len ); GLE = WSAGetLastError(); -todo_wine ok( ret == 0, "WSAStringToAddressA() failed for IPv6 address: %d\n", GLE);
len = sizeof(sockaddr6); @@ -3436,7 +3435,6 @@ todo_wine ret = WSAStringToAddressA( address8, AF_INET6, NULL, (SOCKADDR*)&sockaddr6, &len ); GLE = WSAGetLastError(); -todo_wine ok( ret == 0 && sockaddr6.sin6_port == 0xffff, "WSAStringToAddressA() failed for IPv6 address: %d\n", GLE);
@@ -3568,7 +3566,6 @@ static void test_WSAStringToAddressW(void) ret = WSAStringToAddressW( address7, AF_INET6, NULL, (SOCKADDR*)&sockaddr6, &len ); GLE = WSAGetLastError(); -todo_wine ok( ret == 0, "WSAStringToAddressW() failed for IPv6 address: %d\n", GLE);
len = sizeof(sockaddr6); @@ -3578,7 +3575,6 @@ todo_wine ret = WSAStringToAddressW( address8, AF_INET6, NULL, (SOCKADDR*)&sockaddr6, &len ); GLE = WSAGetLastError(); -todo_wine ok( ret == 0 && sockaddr6.sin6_port == 0xffff, "WSAStringToAddressW() failed for IPv6 address: %d\n", GLE);