[glib] ginetaddress: fix addr/string conversions on windows



commit 59ed934b055229ff2da96f96c772a060dc0f4092
Author: Dan Winship <danw gnome org>
Date:   Sun Jun 2 18:32:21 2013 -0300

    ginetaddress: fix addr/string conversions on windows
    
    When parsing an address, we need to re-set "len" between IPv4 and
    IPv6, since WSAStringToAddress() might set it to sizeof(struct sin_addr)
    when trying to parse the string as IPv4, even if it fails. Also, we
    need to make sure to not pass strings to WSAStringToAddress() that it
    will accept but that we don't want it to.
    
    When stringifying an address, we need to clear the sockaddr before
    filling it in, so we don't accidentally end up with an unwanted
    scope_id or the like.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=701401

 gio/ginetaddress.c |   29 +++++++++++++++++++++--------
 1 files changed, 21 insertions(+), 8 deletions(-)
---
diff --git a/gio/ginetaddress.c b/gio/ginetaddress.c
index de67272..e5357c8 100644
--- a/gio/ginetaddress.c
+++ b/gio/ginetaddress.c
@@ -405,12 +405,26 @@ g_inet_address_new_from_string (const gchar *string)
   g_networking_init ();
 
 #ifdef G_OS_WIN32
-  memset (&sa, 0, sizeof (sa));
-  len = sizeof (sa);
-  if (WSAStringToAddress ((LPTSTR) string, AF_INET, NULL, (LPSOCKADDR) &sa, &len) == 0)
-    return g_inet_address_new_from_bytes ((guint8 *)&sin->sin_addr, AF_INET);
-  else if (WSAStringToAddress ((LPTSTR) string, AF_INET6, NULL, (LPSOCKADDR) &sa, &len) == 0)
-    return g_inet_address_new_from_bytes ((guint8 *)&sin6->sin6_addr, AF_INET6);
+  /* We need to make sure to not pass a string of the form
+   * "IPv4addr:port" or "[IPv6addr]:port" to WSAStringToAddress(),
+   * since it would accept them (returning both the address and the
+   * port), but we only want to accept standalone IP addresses. (In
+   * the IPv6 case, WINE actually only checks for the ']', not the
+   * '[', which is why we do the same here.)
+   */
+  if (!strchr (string, ':'))
+    {
+      len = sizeof (sa);
+      if (WSAStringToAddress ((LPTSTR) string, AF_INET, NULL, (LPSOCKADDR) &sa, &len) == 0)
+        return g_inet_address_new_from_bytes ((guint8 *)&sin->sin_addr, AF_INET);
+    }
+
+  if (!strchr (string, ']'))
+    {
+      len = sizeof (sa);
+      if (WSAStringToAddress ((LPTSTR) string, AF_INET6, NULL, (LPSOCKADDR) &sa, &len) == 0)
+        return g_inet_address_new_from_bytes ((guint8 *)&sin6->sin6_addr, AF_INET6);
+    }
 
 #else /* !G_OS_WIN32 */
 
@@ -529,20 +543,19 @@ g_inet_address_to_string (GInetAddress *address)
   g_return_val_if_fail (G_IS_INET_ADDRESS (address), NULL);
 
 #ifdef G_OS_WIN32
+  memset (&sa, 0, sizeof (sa));
   sa.ss_family = address->priv->family;
   if (address->priv->family == AF_INET)
     {
       addrlen = sizeof (*sin);
       memcpy (&sin->sin_addr, &address->priv->addr.ipv4,
              sizeof (sin->sin_addr));
-      sin->sin_port = 0;
     }
   else
     {
       addrlen = sizeof (*sin6);
       memcpy (&sin6->sin6_addr, &address->priv->addr.ipv6,
              sizeof (sin6->sin6_addr));
-      sin6->sin6_port = 0;
     }
   if (WSAAddressToString ((LPSOCKADDR) &sa, addrlen, NULL, buffer, &buflen) != 0)
     return NULL;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]