[glib] g_dbus_address_escape_value: add



commit d200208d2b8bad7babdd56f4ec6fcae1589e142b
Author: Simon McVittie <simon mcvittie collabora co uk>
Date:   Wed Feb 13 20:42:58 2013 +0000

    g_dbus_address_escape_value: add
    
    This is a GLib reimplementation of dbus_address_escape_value().
    It's useful if you want to construct a D-Bus address from pieces:
    for instance, if you have a listening Unix socket whose path is known,
    and you want to connect a D-Bus peer to it.
    
    Bug: https://bugzilla.gnome.org/show_bug.cgi?id=693673
    Reviewed-by: Colin Walters <walters verbum org>
    [amended to add Since: 2.36 as per review]
    Signed-off-by: Simon McVittie <simon mcvittie collabora co uk>

 gio/gdbusaddress.c          |   47 +++++++++++++++++++++++++++++++++++++++++++
 gio/gdbusaddress.h          |    3 ++
 gio/tests/gdbus-addresses.c |   24 ++++++++++++++++++++++
 3 files changed, 74 insertions(+), 0 deletions(-)
---
diff --git a/gio/gdbusaddress.c b/gio/gdbusaddress.c
index 8c1d31c..cc9703c 100644
--- a/gio/gdbusaddress.c
+++ b/gio/gdbusaddress.c
@@ -1586,3 +1586,50 @@ g_dbus_address_get_for_bus_sync (GBusType       bus_type,
 
   return ret;
 }
+
+/**
+ * g_dbus_address_escape_value:
+ * @string: an unescaped string to be included in a D-Bus address
+ *  as the value in a key-value pair
+ *
+ * Escape @string so it can appear in a D-Bus address as the value
+ * part of a key-value pair.
+ *
+ * For instance, if @string is <code>/run/bus-for-:0</code>,
+ * this function would return <code>/run/bus-for-%3A0</code>,
+ * which could be used in a D-Bus address like
+ * <code>unix:nonce-tcp:host=127.0.0.1,port=42,noncefile=/run/bus-for-%3A0</code>.
+ *
+ * Returns: (transfer full): a copy of @string with all
+ *  non-optionally-escaped bytes escaped
+ *
+ * Since: 2.36
+ */
+gchar *
+g_dbus_address_escape_value (const gchar *string)
+{
+  GString *s;
+  gsize i;
+
+  g_return_val_if_fail (string != NULL, NULL);
+
+  /* There will often not be anything needing escaping at all. */
+  s = g_string_sized_new (strlen (string));
+
+  /* D-Bus address escaping is mostly the same as URI escaping... */
+  g_string_append_uri_escaped (s, string, "\\/", FALSE);
+
+  /* ... but '~' is an unreserved character in URIs, but a
+   * non-optionally-escaped character in D-Bus addresses. */
+  for (i = 0; i < s->len; i++)
+    {
+      if (G_UNLIKELY (s->str[i] == '~'))
+        {
+          s->str[i] = '%';
+          g_string_insert (s, i + 1, "7E");
+          i += 2;
+        }
+    }
+
+  return g_string_free (s, FALSE);
+}
diff --git a/gio/gdbusaddress.h b/gio/gdbusaddress.h
index 55896b8..08773aa 100644
--- a/gio/gdbusaddress.h
+++ b/gio/gdbusaddress.h
@@ -31,6 +31,9 @@
 
 G_BEGIN_DECLS
 
+GLIB_AVAILABLE_IN_2_36
+gchar *g_dbus_address_escape_value (const gchar *string);
+
 GLIB_AVAILABLE_IN_ALL
 gboolean g_dbus_is_address (const gchar *string);
 GLIB_AVAILABLE_IN_ALL
diff --git a/gio/tests/gdbus-addresses.c b/gio/tests/gdbus-addresses.c
index 72388c5..c5a237d 100644
--- a/gio/tests/gdbus-addresses.c
+++ b/gio/tests/gdbus-addresses.c
@@ -102,6 +102,29 @@ test_mixed_address (void)
   g_assert (!g_dbus_is_supported_address ("tcp:host=localhost,port=42;tcp:family=bla", NULL));
 }
 
+static const struct { const char *before; const char *after; } escaping[] = {
+      { "foo", "foo" },
+      { "/.\\-_", "/.\\-_" },
+      { "<=>", "%3C%3D%3E" },
+      { "/foo~1", "/foo%7E1" },
+      { "\xe2\x98\xad\xff", "%E2%98%AD%FF" },
+      { NULL, NULL }
+};
+
+static void
+test_escape_address (void)
+{
+  gsize i;
+
+  for (i = 0; escaping[i].before != NULL; i++)
+    {
+      gchar *s = g_dbus_address_escape_value (escaping[i].before);
+
+      g_assert_cmpstr (s, ==, escaping[i].after);
+      g_free (s);
+    }
+}
+
 int
 main (int   argc,
       char *argv[])
@@ -116,6 +139,7 @@ main (int   argc,
   g_test_add_func ("/gdbus/tcp-address", test_tcp_address);
   g_test_add_func ("/gdbus/autolaunch-address", test_autolaunch_address);
   g_test_add_func ("/gdbus/mixed-address", test_mixed_address);
+  g_test_add_func ("/gdbus/escape-address", test_escape_address);
 
   return g_test_run();
 }


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