WS_getpeername buffer length fix

Francois Gouget fgouget at free.fr
Wed Jan 9 19:38:15 CST 2002


   Damn, my fingers thought I was still in XEmacs!


On Tue, 8 Jan 2002, Paul Rupe wrote:

> While running the Win32 version of perl under Wine (don't ask), I
> noticed that WS_getpeername wasn't returning the length of the output if
> the buffer was larger than needed.  The app was calling getpeername with
> a 256-byte buffer and expecting *namelen to be 16 afterward.  The most
> logical place to fix this was in ws_sockaddr_u2ws.  Other APIs call this
> function, but I think they would also expect the same behavior so it
> should be ok.

   Sorry to reply so late. I think your fix is a good one but with the
patch you sent ws_sockaddr_u2ws never returns -1 anymore. This means the
functions that call it will not do SetLastError(WSAEFAULT) anymore.

   The attached patch should fix that:

Changelog:

 * dlls/winsock/socket.c
   Fix previous patch: the ws_sockaddr_u2ws return value was wrong
   Make ws_sockaddr_{ws2u,u2ws} static

--
Francois Gouget         fgouget at free.fr        http://fgouget.free.fr/
           If it stinks, it's chemistry. If it moves, it's biology.
                  If it does not work, It's computer science.

-------------- next part --------------
Index: dlls/winsock/socket.c
===================================================================
RCS file: /home/wine/wine/dlls/winsock/socket.c,v
retrieving revision 1.74
diff -u -r1.74 socket.c
--- dlls/winsock/socket.c	2002/01/09 21:17:16	1.74
+++ dlls/winsock/socket.c	2002/01/09 23:47:32
@@ -797,7 +797,7 @@
  * start with. Note that the returned pointer may be the original pointer 
  * if no conversion is necessary.
  */
-const struct sockaddr* ws_sockaddr_ws2u(const struct WS_sockaddr* wsaddr, int wsaddrlen, int *uaddrlen)
+static const struct sockaddr* ws_sockaddr_ws2u(const struct WS_sockaddr* wsaddr, int wsaddrlen, int *uaddrlen)
 {
     switch (wsaddr->sa_family)
     {
@@ -849,7 +849,7 @@
 }
 
 /* Returns 0 if successful, -1 if the buffer is too small */
-int ws_sockaddr_u2ws(const struct sockaddr* uaddr, int uaddrlen, struct WS_sockaddr* wsaddr, int* wsaddrlen)
+static int ws_sockaddr_u2ws(const struct sockaddr* uaddr, int uaddrlen, struct WS_sockaddr* wsaddr, int* wsaddrlen)
 {
     int res;
 
@@ -866,6 +866,7 @@
             {
             default:
                 res=0; /* enough */
+                *wsaddrlen=uaddrlen;
                 wsipx->sa_socket=uipx->sipx_port;
                 /* fall through */
             case 13:
@@ -896,9 +897,13 @@
 
     default:
         /* No conversion needed */
-        *wsaddrlen = min(*wsaddrlen,uaddrlen);
         memcpy(wsaddr,uaddr,*wsaddrlen);
-        res=(*wsaddrlen<uaddrlen?-1:0);
+        if (*wsaddrlen<uaddrlen) {
+            res=-1;
+        } else {
+            *wsaddrlen=uaddrlen;
+            res=0;
+        }
     }
     return res;
 }


More information about the wine-patches mailing list