From bed1525fa40ca4190500efc03d11a8f0c6ee4704 Mon Sep 17 00:00:00 2001 From: Qian Hong Date: Thu, 12 Mar 2015 01:08:09 +0800 Subject: [PATCH] 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 a3b6b264792..960556d552a 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 ec4b563b90a..ca8e1a561ae 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();