[glib] Fix IPv6 parsing in _g_uri_parse_authority, add _g_uri_from_authority



commit 59383c8bea00b8f4bf50cf82ae9f3e7ce1df1a03
Author: Dan Winship <danw gnome org>
Date:   Fri Sep 10 08:51:21 2010 -0400

    Fix IPv6 parsing in _g_uri_parse_authority, add _g_uri_from_authority
    
    Fixes connections to IPv6 address literals.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=629259

 gio/gnetworkaddress.c    |   49 +++++++++++++++++++++++++++++++++++++++++++--
 gio/gnetworkingprivate.h |    4 +++
 gio/gnetworkservice.c    |    9 ++++---
 gio/gsocketaddress.c     |    2 +-
 4 files changed, 56 insertions(+), 8 deletions(-)
---
diff --git a/gio/gnetworkaddress.c b/gio/gnetworkaddress.c
index 80a3e31..11bda8c 100644
--- a/gio/gnetworkaddress.c
+++ b/gio/gnetworkaddress.c
@@ -526,6 +526,8 @@ _g_uri_parse_authority (const char  *uri,
   /* If IPv6 or IPvFuture */
   if (*p == '[')
     {
+      start++;
+      p++;
       while (1)
 	{
 	  c = *p++;
@@ -625,6 +627,46 @@ error:
   return FALSE;
 }
 
+gchar *
+_g_uri_from_authority (const gchar *protocol,
+                       const gchar *host,
+                       guint        port,
+                       const gchar *userinfo)
+{
+  GString *uri;
+
+  uri = g_string_new (protocol);
+  g_string_append (uri, "://");
+
+  if (userinfo)
+    {
+      g_string_append_uri_escaped (uri, userinfo, G_URI_RESERVED_CHARS_ALLOWED_IN_USERINFO, FALSE);
+      g_string_append_c (uri, '@');
+    }
+
+  if (g_hostname_is_non_ascii (host))
+    {
+      gchar *ace_encoded = g_hostname_to_ascii (host);
+
+      if (!ace_encoded)
+        {
+          g_string_free (uri, TRUE);
+          return NULL;
+        }
+      g_string_append (uri, ace_encoded);
+      g_free (ace_encoded);
+    }
+  else if (strchr (host, ':'))
+    g_string_append_printf (uri, "[%s]", host);
+  else
+    g_string_append (uri, host);
+
+  if (port != 0)
+    g_string_append_printf (uri, ":%u", port);
+
+  return g_string_free (uri, FALSE);
+}
+
 /**
  * g_network_address_parse_uri:
  * @uri: the hostname and optionally a port
@@ -920,9 +962,10 @@ g_network_address_connectable_proxy_enumerate (GSocketConnectable *connectable)
   GSocketAddressEnumerator *proxy_enum;
   gchar *uri;
 
-  uri = g_strdup_printf ("%s://%s:%u",
-      	                 self->priv->scheme ? self->priv->scheme : "none",
-                         self->priv->hostname, self->priv->port);
+  uri = _g_uri_from_authority (self->priv->scheme ? self->priv->scheme : "none",
+                               self->priv->hostname,
+                               self->priv->port,
+                               NULL);
 
   proxy_enum = g_object_new (G_TYPE_PROXY_ADDRESS_ENUMERATOR,
                              "connectable", connectable,
diff --git a/gio/gnetworkingprivate.h b/gio/gnetworkingprivate.h
index 9434adf..92d2645 100644
--- a/gio/gnetworkingprivate.h
+++ b/gio/gnetworkingprivate.h
@@ -124,6 +124,10 @@ gboolean _g_uri_parse_authority            (const char       *uri,
 					    char            **host,
 					    guint16          *port,
 					    char            **userinfo);
+gchar *  _g_uri_from_authority             (const gchar      *protocol,
+					    const gchar      *host,
+					    guint             port,
+					    const gchar      *userinfo);
 
 G_END_DECLS
 
diff --git a/gio/gnetworkservice.c b/gio/gnetworkservice.c
index e46126a..b1d934d 100644
--- a/gio/gnetworkservice.c
+++ b/gio/gnetworkservice.c
@@ -31,6 +31,7 @@
 #include "ginetsocketaddress.h"
 #include "gioerror.h"
 #include "gnetworkaddress.h"
+#include "gnetworkingprivate.h"
 #include "gresolver.h"
 #include "gsimpleasyncresult.h"
 #include "gsocketaddressenumerator.h"
@@ -438,10 +439,10 @@ g_network_service_address_enumerator_next (GSocketAddressEnumerator  *enumerator
               continue;
             }
 
-          uri = g_strdup_printf ("%s://%s:%u",
-                                 g_network_service_get_scheme (srv_enum->srv),
-                                 hostname,
-                                 g_srv_target_get_port (target));
+          uri = _g_uri_from_authority (g_network_service_get_scheme (srv_enum->srv),
+                                       hostname,
+                                       g_srv_target_get_port (target),
+                                       NULL);
           g_free (hostname);
 
           addr = g_network_address_parse_uri (uri,
diff --git a/gio/gsocketaddress.c b/gio/gsocketaddress.c
index 49220b4..d4dcbb0 100644
--- a/gio/gsocketaddress.c
+++ b/gio/gsocketaddress.c
@@ -372,7 +372,7 @@ g_socket_address_connectable_proxy_enumerate (GSocketConnectable *connectable)
       g_object_get (connectable, "address", &addr, "port", &port, NULL);
 
       ip = g_inet_address_to_string (addr);
-      uri = g_strdup_printf ("none://%s:%u", ip, port);
+      uri = _g_uri_from_authority ("none", ip, port, NULL);
 
       addr_enum = g_object_new (G_TYPE_PROXY_ADDRESS_ENUMERATOR,
       	       	       	       	"connectable", connectable,



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