mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-08-20 07:38:54 +02:00
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
This commit is contained in:
@@ -405,12 +405,26 @@ g_inet_address_new_from_string (const gchar *string)
|
|||||||
g_networking_init ();
|
g_networking_init ();
|
||||||
|
|
||||||
#ifdef G_OS_WIN32
|
#ifdef G_OS_WIN32
|
||||||
memset (&sa, 0, sizeof (sa));
|
/* We need to make sure to not pass a string of the form
|
||||||
len = sizeof (sa);
|
* "IPv4addr:port" or "[IPv6addr]:port" to WSAStringToAddress(),
|
||||||
if (WSAStringToAddress ((LPTSTR) string, AF_INET, NULL, (LPSOCKADDR) &sa, &len) == 0)
|
* since it would accept them (returning both the address and the
|
||||||
return g_inet_address_new_from_bytes ((guint8 *)&sin->sin_addr, AF_INET);
|
* port), but we only want to accept standalone IP addresses. (In
|
||||||
else if (WSAStringToAddress ((LPTSTR) string, AF_INET6, NULL, (LPSOCKADDR) &sa, &len) == 0)
|
* the IPv6 case, WINE actually only checks for the ']', not the
|
||||||
return g_inet_address_new_from_bytes ((guint8 *)&sin6->sin6_addr, AF_INET6);
|
* '[', 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 */
|
#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);
|
g_return_val_if_fail (G_IS_INET_ADDRESS (address), NULL);
|
||||||
|
|
||||||
#ifdef G_OS_WIN32
|
#ifdef G_OS_WIN32
|
||||||
|
memset (&sa, 0, sizeof (sa));
|
||||||
sa.ss_family = address->priv->family;
|
sa.ss_family = address->priv->family;
|
||||||
if (address->priv->family == AF_INET)
|
if (address->priv->family == AF_INET)
|
||||||
{
|
{
|
||||||
addrlen = sizeof (*sin);
|
addrlen = sizeof (*sin);
|
||||||
memcpy (&sin->sin_addr, &address->priv->addr.ipv4,
|
memcpy (&sin->sin_addr, &address->priv->addr.ipv4,
|
||||||
sizeof (sin->sin_addr));
|
sizeof (sin->sin_addr));
|
||||||
sin->sin_port = 0;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
addrlen = sizeof (*sin6);
|
addrlen = sizeof (*sin6);
|
||||||
memcpy (&sin6->sin6_addr, &address->priv->addr.ipv6,
|
memcpy (&sin6->sin6_addr, &address->priv->addr.ipv6,
|
||||||
sizeof (sin6->sin6_addr));
|
sizeof (sin6->sin6_addr));
|
||||||
sin6->sin6_port = 0;
|
|
||||||
}
|
}
|
||||||
if (WSAAddressToString ((LPSOCKADDR) &sa, addrlen, NULL, buffer, &buflen) != 0)
|
if (WSAAddressToString ((LPSOCKADDR) &sa, addrlen, NULL, buffer, &buflen) != 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
Reference in New Issue
Block a user