Kai Blin : ws2_32: Return WSAEINVAL for unhandled address families in WSAStringToAddress.

Alexandre Julliard julliard at wine.codeweavers.com
Fri Jun 29 08:15:00 CDT 2007


Module: wine
Branch: master
Commit: d89f2b4810ebbef1deb3b4377e5af44d09c6ef74
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=d89f2b4810ebbef1deb3b4377e5af44d09c6ef74

Author: Kai Blin <kai.blin at gmail.com>
Date:   Fri Jun 29 12:41:28 2007 +0200

ws2_32: Return WSAEINVAL for unhandled address families in WSAStringToAddress.

Prepare for IPv6 support.

---

 dlls/ws2_32/socket.c     |  122 +++++++++++++++++++++++++++-------------------
 dlls/ws2_32/tests/sock.c |   73 +++++++++++++++++++++++++++
 2 files changed, 144 insertions(+), 51 deletions(-)

diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index 92fd3f6..90fa9b0 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -4429,7 +4429,6 @@ INT WINAPI WSAStringToAddressA(LPSTR AddressString,
                                LPINT lpAddressLength)
 {
     INT res=0;
-    struct in_addr inetaddr;
     LPSTR workBuffer=NULL,ptrPort;
 
     TRACE( "(%s, %x, %p, %p, %p)\n", AddressString, AddressFamily, lpProtocolInfo,
@@ -4437,63 +4436,84 @@ INT WINAPI WSAStringToAddressA(LPSTR AddressString,
 
     if (!lpAddressLength || !lpAddress) return SOCKET_ERROR;
 
-    if (AddressString)
+    if (!AddressString)
     {
-        workBuffer = HeapAlloc( GetProcessHeap(), 0, strlen(AddressString)+1 );
-        if (workBuffer)
+        WSASetLastError(WSAEINVAL);
+        return SOCKET_ERROR;
+    }
+
+    if (lpProtocolInfo)
+        FIXME("ProtocolInfo not implemented.\n");
+
+    workBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+                            strlen(AddressString) + 1);
+    if (!workBuffer)
+    {
+        WSASetLastError(WSA_NOT_ENOUGH_MEMORY);
+        return SOCKET_ERROR;
+    }
+
+    strcpy(workBuffer, AddressString);
+
+    switch(AddressFamily)
+    {
+    case AF_INET:
+    {
+        struct in_addr inetaddr;
+
+        /* If lpAddressLength is too small, tell caller the size we need */
+        if (*lpAddressLength < sizeof(SOCKADDR_IN))
         {
-            strcpy(workBuffer,AddressString);
-            switch (AddressFamily)
-            {
-            case AF_INET:
-                /* caller wants to know the size of the socket buffer */
-                if (*lpAddressLength < sizeof(SOCKADDR_IN))
-                {
-                    *lpAddressLength = sizeof(SOCKADDR_IN);
-                    res = WSAEFAULT;
-                }
-                else
-                {
-                    /* caller wants to translate an AddressString into a SOCKADDR */
-                    if (lpAddress)
-                    {
-                        memset(lpAddress,0,sizeof(SOCKADDR_IN));
-                        ((LPSOCKADDR_IN)lpAddress)->sin_family = AF_INET;
-                        ptrPort = strchr(workBuffer,':');
-                        if (ptrPort)
-                        {
-                            ((LPSOCKADDR_IN)lpAddress)->sin_port = (WS_u_short)atoi(ptrPort+1);
-                            *ptrPort = '\0';
-                        }
-                        else
-                            ((LPSOCKADDR_IN)lpAddress)->sin_port = 0;
-                        if (inet_aton(workBuffer, &inetaddr) > 0)
-                        {
-                            ((LPSOCKADDR_IN)lpAddress)->sin_addr.WS_s_addr = inetaddr.s_addr;
-                            res = 0;
-                        }
-                        else
-                            res = WSAEINVAL;
-                    }
-                }
-                if (lpProtocolInfo)
-                    FIXME("(%s, %x, %p, %p, %p) - ProtocolInfo not implemented!\n",
-                        AddressString, AddressFamily,
-                        lpProtocolInfo, lpAddress, lpAddressLength);
+            *lpAddressLength = sizeof(SOCKADDR_IN);
+            res = WSAEFAULT;
+            break;
+        }
+        memset(lpAddress, 0, sizeof(SOCKADDR_IN));
 
-                break;
-            default:
-                FIXME("(%s, %x, %p, %p, %p) - AddressFamiliy not implemented!\n",
-                    AddressString, AddressFamily,
-                    lpProtocolInfo, lpAddress, lpAddressLength);
-            }
-            HeapFree( GetProcessHeap(), 0, workBuffer );
+        ((LPSOCKADDR_IN)lpAddress)->sin_family = AF_INET;
+
+        ptrPort = strchr(workBuffer, ':');
+        if(ptrPort)
+        {
+            ((LPSOCKADDR_IN)lpAddress)->sin_port = (WS_u_short)atoi(ptrPort+1);
+            *ptrPort = '\0';
         }
         else
-            res = WSA_NOT_ENOUGH_MEMORY;
+        {
+            ((LPSOCKADDR_IN)lpAddress)->sin_port = 0;
+        }
+
+        if(inet_aton(workBuffer, &inetaddr) > 0)
+        {
+            ((LPSOCKADDR_IN)lpAddress)->sin_addr.WS_s_addr = inetaddr.s_addr;
+            res = 0;
+        }
+        else
+            res = WSAEINVAL;
+
+        break;
+
     }
-    else
+    case AF_INET6:
+    {
+        /* If lpAddressLength is too small, tell caller the size we need */
+        if (*lpAddressLength < sizeof(SOCKADDR_IN6))
+        {
+            *lpAddressLength = sizeof(SOCKADDR_IN6);
+            res = WSAEFAULT;
+            break;
+        }
+        FIXME("We don't support IPv6 yet.\n");
         res = WSAEINVAL;
+        break;
+    }
+    default:
+        /* According to MSDN, only AF_INET and AF_INET6 are supported. */
+        TRACE("Unsupported address family specified: %d.\n", AddressFamily);
+        res = WSAEINVAL;
+    }
+
+    HeapFree(GetProcessHeap(), 0, workBuffer);
 
     if (!res) return 0;
     WSASetLastError(res);
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c
index cc41320..7eb6d38 100644
--- a/dlls/ws2_32/tests/sock.c
+++ b/dlls/ws2_32/tests/sock.c
@@ -24,6 +24,7 @@
 #include <windef.h>
 #include <winbase.h>
 #include <winsock2.h>
+#include <ws2tcpip.h>
 #include <mswsock.h>
 #include "wine/test.h"
 #include <winnt.h>
@@ -1250,6 +1251,7 @@ static void test_WSAStringToAddressA(void)
 {
     INT ret, len;
     SOCKADDR_IN sockaddr;
+    SOCKADDR_IN6 sockaddr6;
     int GLE;
 
     CHAR address1[] = "0.0.0.0";
@@ -1257,6 +1259,9 @@ static void test_WSAStringToAddressA(void)
     CHAR address3[] = "255.255.255.255";
     CHAR address4[] = "127.127.127.127:65535";
     CHAR address5[] = "255.255.255.255:65535";
+    CHAR address6[] = "::1";
+    CHAR address7[] = "[::1]";
+    CHAR address8[] = "[::1]:65535";
 
     len = 0;
     sockaddr.sin_family = AF_INET;
@@ -1308,12 +1313,45 @@ static void test_WSAStringToAddressA(void)
     ok( (ret == 0 && sockaddr.sin_addr.s_addr == 0xffffffff && sockaddr.sin_port == 0xffff) || 
         (ret == SOCKET_ERROR && (GLE == ERROR_INVALID_PARAMETER || GLE == WSAEINVAL)),
         "WSAStringToAddressA() failed unexpectedly: %d\n", GLE );
+
+    len = sizeof(sockaddr6);
+    memset(&sockaddr6, 0, len);
+    sockaddr6.sin6_family = AF_INET6;
+
+    ret = WSAStringToAddressA( address6, AF_INET6, NULL, (SOCKADDR*)&sockaddr6,
+            &len );
+    GLE = WSAGetLastError();
+    ok( ret == 0 || (ret == SOCKET_ERROR && GLE == WSAEINVAL),
+        "WSAStringToAddressA() failed for IPv6 address: %d\n", GLE);
+
+    len = sizeof(sockaddr6);
+    memset(&sockaddr6, 0, len);
+    sockaddr6.sin6_family = AF_INET6;
+
+    ret = WSAStringToAddressA( address7, AF_INET6, NULL, (SOCKADDR*)&sockaddr6,
+            &len );
+    GLE = WSAGetLastError();
+    ok( ret == 0 || (ret == SOCKET_ERROR && GLE == WSAEINVAL),
+        "WSAStringToAddressA() failed for IPv6 address: %d\n", GLE);
+
+    len = sizeof(sockaddr6);
+    memset(&sockaddr6, 0, len);
+    sockaddr6.sin6_family = AF_INET6;
+
+    ret = WSAStringToAddressA( address8, AF_INET6, NULL, (SOCKADDR*)&sockaddr6,
+            &len );
+    GLE = WSAGetLastError();
+    ok( (ret == 0 && sockaddr6.sin6_port == 0xffff) ||
+        (ret == SOCKET_ERROR && GLE == WSAEINVAL),
+        "WSAStringToAddressA() failed for IPv6 address: %d\n", GLE);
+
 }
 
 static void test_WSAStringToAddressW(void)
 {
     INT ret, len;
     SOCKADDR_IN sockaddr;
+    SOCKADDR_IN6 sockaddr6;
     int GLE;
 
     WCHAR address1[] = { '0','.','0','.','0','.','0', 0 };
@@ -1323,6 +1361,9 @@ static void test_WSAStringToAddressW(void)
                          ':', '6', '5', '5', '3', '5', 0 };
     WCHAR address5[] = { '2','5','5','.','2','5','5','.','2','5','5','.','2','5','5', ':',
                          '6', '5', '5', '3', '5', 0 };
+    WCHAR address6[] = {':',':','1','\0'};
+    WCHAR address7[] = {'[',':',':','1',']','\0'};
+    WCHAR address8[] = {'[',':',':','1',']',':','6','5','5','3','5','\0'};
 
     len = 0;
     sockaddr.sin_family = AF_INET;
@@ -1373,6 +1414,38 @@ static void test_WSAStringToAddressW(void)
     ok( (ret == 0 && sockaddr.sin_addr.s_addr == 0xffffffff && sockaddr.sin_port == 0xffff) || 
         (ret == SOCKET_ERROR && (GLE == ERROR_INVALID_PARAMETER || GLE == WSAEINVAL)),
         "WSAStringToAddressW() failed unexpectedly: %d\n", GLE );
+
+    len = sizeof(sockaddr6);
+    memset(&sockaddr6, 0, len);
+    sockaddr6.sin6_family = AF_INET6;
+
+    ret = WSAStringToAddressW( address6, AF_INET6, NULL, (SOCKADDR*)&sockaddr6,
+            &len );
+    GLE = WSAGetLastError();
+    ok( ret == 0 || (ret == SOCKET_ERROR && GLE == WSAEINVAL),
+        "WSAStringToAddressW() failed for IPv6 address: %d\n", GLE);
+
+    len = sizeof(sockaddr6);
+    memset(&sockaddr6, 0, len);
+    sockaddr6.sin6_family = AF_INET6;
+
+    ret = WSAStringToAddressW( address7, AF_INET6, NULL, (SOCKADDR*)&sockaddr6,
+            &len );
+    GLE = WSAGetLastError();
+    ok( ret == 0 || (ret == SOCKET_ERROR && GLE == WSAEINVAL),
+        "WSAStringToAddressW() failed for IPv6 address: %d\n", GLE);
+
+    len = sizeof(sockaddr6);
+    memset(&sockaddr6, 0, len);
+    sockaddr6.sin6_family = AF_INET6;
+
+    ret = WSAStringToAddressW( address8, AF_INET6, NULL, (SOCKADDR*)&sockaddr6,
+            &len );
+    GLE = WSAGetLastError();
+    ok( (ret == 0 && sockaddr6.sin6_port == 0xffff) ||
+        (ret == SOCKET_ERROR && GLE == WSAEINVAL),
+        "WSAStringToAddressW() failed for IPv6 address: %d\n", GLE);
+
 }
 
 static VOID WINAPI SelectReadThread(select_thread_params *par)




More information about the wine-cvs mailing list