Qian Hong : ws2_32: Improved error handling in gethostname when name length is insufficient.

Alexandre Julliard julliard at wine.codeweavers.com
Fri Mar 13 08:44:26 CDT 2015


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

Author: Qian Hong <qhong at codeweavers.com>
Date:   Thu Mar 12 01:08:09 2015 +0800

ws2_32: Improved error handling in gethostname when name length is insufficient.

---

 dlls/ws2_32/socket.c     | 31 +++++++++++++++++++++++++------
 dlls/ws2_32/tests/sock.c | 34 ++++++++++++++++++++++++++++++++++
 2 files changed, 59 insertions(+), 6 deletions(-)

diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index a3b6b26..960556d 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -6056,16 +6056,35 @@ struct WS_servent* WINAPI WS_getservbyport(int port, const char *proto)
  */
 int WINAPI WS_gethostname(char *name, int namelen)
 {
+    char buf[256];
+    int len;
+
     TRACE("name %p, len %d\n", name, namelen);
 
-    if (gethostname(name, namelen) == 0)
+    if (!name)
     {
-        TRACE("<- '%s'\n", name);
-        return 0;
+        SetLastError(WSAEFAULT);
+        return SOCKET_ERROR;
     }
-    SetLastError((errno == EINVAL) ? WSAEFAULT : wsaErrno());
-    TRACE("<- ERROR !\n");
-    return SOCKET_ERROR;
+
+    if (gethostname(buf, sizeof(buf)) != 0)
+    {
+        SetLastError(wsaErrno());
+        return SOCKET_ERROR;
+    }
+
+    TRACE("<- '%s'\n", buf);
+    len = strlen(buf);
+    if (len > 15)
+        WARN("Windows supports NetBIOS name length up to 15 bytes!\n");
+    if (namelen <= len)
+    {
+        SetLastError(WSAEFAULT);
+        WARN("<- not enough space for hostname, required %d, got %d!\n", len + 1, namelen);
+        return SOCKET_ERROR;
+    }
+    strcpy(name, buf);
+    return 0;
 }
 
 
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c
index ec4b563..ca8e1a5 100644
--- a/dlls/ws2_32/tests/sock.c
+++ b/dlls/ws2_32/tests/sock.c
@@ -4215,6 +4215,39 @@ static void test_gethostbyname_hack(void)
      * resolve nonexistent host names to addresses of the ISP's spam pages. */
 }
 
+static void test_gethostname(void)
+{
+    struct hostent *he;
+    char name[256];
+    int ret, len;
+
+    WSASetLastError(0xdeadbeef);
+    ret = gethostname(NULL, 256);
+    ok(ret == -1, "gethostname() returned %d\n", ret);
+    ok(WSAGetLastError() == WSAEFAULT, "gethostname with null buffer "
+            "failed with %d, expected %d\n", WSAGetLastError(), WSAEFAULT);
+
+    ret = gethostname(name, sizeof(name));
+    ok(ret == 0, "gethostname() call failed: %d\n", WSAGetLastError());
+    he = gethostbyname(name);
+    ok(he != NULL, "gethostbyname(\"%s\") failed: %d\n", name, WSAGetLastError());
+
+    len = strlen(name);
+    WSASetLastError(0xdeadbeef);
+    strcpy(name, "deadbeef");
+    ret = gethostname(name, len);
+    ok(ret == -1, "gethostname() returned %d\n", ret);
+    ok(!strcmp(name, "deadbeef"), "name changed unexpected!\n");
+    ok(WSAGetLastError() == WSAEFAULT, "gethostname with insufficient length "
+            "failed with %d, expected %d\n", WSAGetLastError(), WSAEFAULT);
+
+    len++;
+    ret = gethostname(name, len);
+    ok(ret == 0, "gethostname() call failed: %d\n", WSAGetLastError());
+    he = gethostbyname(name);
+    ok(he != NULL, "gethostbyname(\"%s\") failed: %d\n", name, WSAGetLastError());
+}
+
 static void test_inet_addr(void)
 {
     u_long addr;
@@ -8437,6 +8470,7 @@ START_TEST( sock )
     test_ioctlsocket();
     test_dns();
     test_gethostbyname_hack();
+    test_gethostname();
 
     test_WSASendMsg();
     test_WSASendTo();




More information about the wine-cvs mailing list