1 /* GDBus - GLib D-Bus Library
3 * Copyright (C) 2008-2010 Red Hat, Inc.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General
16 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 * Author: David Zeuthen <davidz@redhat.com>
26 #include "gdbusutils.h"
32 * @title: D-Bus Utilities
33 * @short_description: Various utilities related to D-Bus
36 * Various utility routines related to D-Bus.
40 is_valid_bus_name_character (gint c,
41 gboolean allow_hyphen)
44 (c >= '0' && c <= '9') ||
45 (c >= 'A' && c <= 'Z') ||
46 (c >= 'a' && c <= 'z') ||
48 (allow_hyphen && c == '-');
52 is_valid_initial_bus_name_character (gint c,
53 gboolean allow_initial_digit,
54 gboolean allow_hyphen)
56 if (allow_initial_digit)
57 return is_valid_bus_name_character (c, allow_hyphen);
60 (c >= 'A' && c <= 'Z') ||
61 (c >= 'a' && c <= 'z') ||
63 (allow_hyphen && c == '-');
67 is_valid_name (const gchar *start,
69 gboolean allow_initial_digit,
70 gboolean allow_hyphen)
90 if (G_UNLIKELY (!is_valid_initial_bus_name_character (*s, allow_initial_digit, allow_hyphen)))
94 else if (G_UNLIKELY (!is_valid_bus_name_character (*s, allow_hyphen)))
101 if (G_UNLIKELY (!has_dot))
112 * @string: The string to check.
114 * Checks if @string is a valid D-Bus bus name (either unique or well-known).
116 * Returns: %TRUE if valid, %FALSE otherwise.
121 g_dbus_is_name (const gchar *string)
127 g_return_val_if_fail (string != NULL, FALSE);
131 len = strlen (string);
132 if (G_UNLIKELY (len == 0 || len > 255))
138 /* handle unique name */
139 if (!is_valid_name (s + 1, len - 1, TRUE, TRUE))
144 else if (G_UNLIKELY (*s == '.'))
146 /* can't start with a . */
149 else if (G_UNLIKELY (!is_valid_initial_bus_name_character (*s, FALSE, TRUE)))
152 ret = is_valid_name (s + 1, len - 1, FALSE, TRUE);
159 * g_dbus_is_unique_name:
160 * @string: The string to check.
162 * Checks if @string is a valid D-Bus unique bus name.
164 * Returns: %TRUE if valid, %FALSE otherwise.
169 g_dbus_is_unique_name (const gchar *string)
174 g_return_val_if_fail (string != NULL, FALSE);
178 len = strlen (string);
179 if (G_UNLIKELY (len == 0 || len > 255))
182 if (G_UNLIKELY (*string != ':'))
185 if (G_UNLIKELY (!is_valid_name (string + 1, len - 1, TRUE, TRUE)))
195 * g_dbus_is_member_name:
196 * @string: The string to check.
198 * Checks if @string is a valid D-Bus member (e.g. signal or method) name.
200 * Returns: %TRUE if valid, %FALSE otherwise.
205 g_dbus_is_member_name (const gchar *string)
211 if (G_UNLIKELY (string == NULL))
214 if (G_UNLIKELY (!is_valid_initial_bus_name_character (string[0], FALSE, FALSE)))
217 for (n = 1; string[n] != '\0'; n++)
219 if (G_UNLIKELY (!is_valid_bus_name_character (string[n], FALSE)))
232 * g_dbus_is_interface_name:
233 * @string: The string to check.
235 * Checks if @string is a valid D-Bus interface name.
237 * Returns: %TRUE if valid, %FALSE otherwise.
242 g_dbus_is_interface_name (const gchar *string)
248 g_return_val_if_fail (string != NULL, FALSE);
252 len = strlen (string);
253 if (G_UNLIKELY (len == 0 || len > 255))
257 if (G_UNLIKELY (*s == '.'))
259 /* can't start with a . */
262 else if (G_UNLIKELY (!is_valid_initial_bus_name_character (*s, FALSE, FALSE)))
265 ret = is_valid_name (s + 1, len - 1, FALSE, FALSE);
272 * g_dbus_is_error_name:
273 * @string: The string to check.
275 * Check whether @string is a valid D-Bus error name.
277 * This function returns the same result as g_dbus_is_interface_name(),
278 * because D-Bus error names are defined to have exactly the
279 * same syntax as interface names.
281 * Returns: %TRUE if valid, %FALSE otherwise.
286 g_dbus_is_error_name (const gchar *string)
288 /* Error names are the same syntax as interface names.
289 * See https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-error */
290 return g_dbus_is_interface_name (string);
293 /* ---------------------------------------------------------------------------------------------------- */
295 /* TODO: maybe move to glib? if so, it should conform to http://en.wikipedia.org/wiki/Guid and/or
296 * http://tools.ietf.org/html/rfc4122 - specifically it should have hyphens then.
300 * g_dbus_generate_guid:
302 * Generate a D-Bus GUID that can be used with
303 * e.g. g_dbus_connection_new().
306 * [D-Bus specification](https://dbus.freedesktop.org/doc/dbus-specification.html#uuids)
307 * regarding what strings are valid D-Bus GUIDs. The specification refers to
308 * these as ‘UUIDs’ whereas GLib (for historical reasons) refers to them as
309 * ‘GUIDs’. The terms are interchangeable.
311 * Note that D-Bus GUIDs do not follow
312 * [RFC 4122](https://datatracker.ietf.org/doc/html/rfc4122).
314 * Returns: A valid D-Bus GUID. Free with g_free().
319 g_dbus_generate_guid (void)
327 s = g_string_new (NULL);
329 r1 = g_random_int ();
330 r2 = g_random_int ();
331 r3 = g_random_int ();
332 now_us = g_get_real_time ();
334 g_string_append_printf (s, "%08x", r1);
335 g_string_append_printf (s, "%08x", r2);
336 g_string_append_printf (s, "%08x", r3);
337 g_string_append_printf (s, "%08x", (guint32) (now_us / G_USEC_PER_SEC));
339 return g_string_free (s, FALSE);
344 * @string: The string to check.
346 * Checks if @string is a D-Bus GUID.
348 * See the documentation for g_dbus_generate_guid() for more information about
349 * the format of a GUID.
351 * Returns: %TRUE if @string is a GUID, %FALSE otherwise.
356 g_dbus_is_guid (const gchar *string)
361 g_return_val_if_fail (string != NULL, FALSE);
365 for (n = 0; n < 32; n++)
367 if (!g_ascii_isxdigit (string[n]))
370 if (string[32] != '\0')
379 /* ---------------------------------------------------------------------------------------------------- */
382 * g_dbus_gvariant_to_gvalue:
383 * @value: A #GVariant.
384 * @out_gvalue: (out): Return location pointing to a zero-filled (uninitialized) #GValue.
386 * Converts a #GVariant to a #GValue. If @value is floating, it is consumed.
388 * The rules specified in the g_dbus_gvalue_to_gvariant() function are
389 * used - this function is essentially its reverse form. So, a #GVariant
390 * containing any basic or string array type will be converted to a #GValue
391 * containing a basic value or string array. Any other #GVariant (handle,
392 * variant, tuple, dict entry) will be converted to a #GValue containing that
395 * The conversion never fails - a valid #GValue is always returned in
401 g_dbus_gvariant_to_gvalue (GVariant *value,
404 const GVariantType *type;
407 g_return_if_fail (value != NULL);
408 g_return_if_fail (out_gvalue != NULL);
410 memset (out_gvalue, '\0', sizeof (GValue));
412 switch (g_variant_classify (value))
414 case G_VARIANT_CLASS_BOOLEAN:
415 g_value_init (out_gvalue, G_TYPE_BOOLEAN);
416 g_value_set_boolean (out_gvalue, g_variant_get_boolean (value));
419 case G_VARIANT_CLASS_BYTE:
420 g_value_init (out_gvalue, G_TYPE_UCHAR);
421 g_value_set_uchar (out_gvalue, g_variant_get_byte (value));
424 case G_VARIANT_CLASS_INT16:
425 g_value_init (out_gvalue, G_TYPE_INT);
426 g_value_set_int (out_gvalue, g_variant_get_int16 (value));
429 case G_VARIANT_CLASS_UINT16:
430 g_value_init (out_gvalue, G_TYPE_UINT);
431 g_value_set_uint (out_gvalue, g_variant_get_uint16 (value));
434 case G_VARIANT_CLASS_INT32:
435 g_value_init (out_gvalue, G_TYPE_INT);
436 g_value_set_int (out_gvalue, g_variant_get_int32 (value));
439 case G_VARIANT_CLASS_UINT32:
440 g_value_init (out_gvalue, G_TYPE_UINT);
441 g_value_set_uint (out_gvalue, g_variant_get_uint32 (value));
444 case G_VARIANT_CLASS_INT64:
445 g_value_init (out_gvalue, G_TYPE_INT64);
446 g_value_set_int64 (out_gvalue, g_variant_get_int64 (value));
449 case G_VARIANT_CLASS_UINT64:
450 g_value_init (out_gvalue, G_TYPE_UINT64);
451 g_value_set_uint64 (out_gvalue, g_variant_get_uint64 (value));
454 case G_VARIANT_CLASS_FLOAT:
455 g_value_init (out_gvalue, G_TYPE_FLOAT);
456 g_value_set_float (out_gvalue, g_variant_get_float (value));
459 case G_VARIANT_CLASS_DOUBLE:
460 g_value_init (out_gvalue, G_TYPE_DOUBLE);
461 g_value_set_double (out_gvalue, g_variant_get_double (value));
464 case G_VARIANT_CLASS_STRING:
465 g_value_init (out_gvalue, G_TYPE_STRING);
466 g_value_set_string (out_gvalue, g_variant_get_string (value, NULL));
469 case G_VARIANT_CLASS_OBJECT_PATH:
470 g_value_init (out_gvalue, G_TYPE_STRING);
471 g_value_set_string (out_gvalue, g_variant_get_string (value, NULL));
474 case G_VARIANT_CLASS_SIGNATURE:
475 g_value_init (out_gvalue, G_TYPE_STRING);
476 g_value_set_string (out_gvalue, g_variant_get_string (value, NULL));
479 case G_VARIANT_CLASS_ARRAY:
480 type = g_variant_get_type (value);
481 switch (g_variant_type_peek_string (type)[1])
483 case G_VARIANT_CLASS_BYTE:
484 g_value_init (out_gvalue, G_TYPE_STRING);
485 g_value_set_string (out_gvalue, g_variant_get_bytestring (value));
488 case G_VARIANT_CLASS_STRING:
489 g_value_init (out_gvalue, G_TYPE_STRV);
490 array = g_variant_dup_strv (value, NULL);
491 g_value_take_boxed (out_gvalue, array);
494 case G_VARIANT_CLASS_OBJECT_PATH:
495 g_value_init (out_gvalue, G_TYPE_STRV);
496 array = g_variant_dup_objv (value, NULL);
497 g_value_take_boxed (out_gvalue, array);
500 case G_VARIANT_CLASS_ARRAY:
501 switch (g_variant_type_peek_string (type)[2])
503 case G_VARIANT_CLASS_BYTE:
504 g_value_init (out_gvalue, G_TYPE_STRV);
505 array = g_variant_dup_bytestring_array (value, NULL);
506 g_value_take_boxed (out_gvalue, array);
510 g_value_init (out_gvalue, G_TYPE_VARIANT);
511 g_value_set_variant (out_gvalue, value);
517 g_value_init (out_gvalue, G_TYPE_VARIANT);
518 g_value_set_variant (out_gvalue, value);
523 case G_VARIANT_CLASS_HANDLE:
524 case G_VARIANT_CLASS_VARIANT:
525 case G_VARIANT_CLASS_MAYBE:
526 case G_VARIANT_CLASS_TUPLE:
527 case G_VARIANT_CLASS_DICT_ENTRY:
528 g_value_init (out_gvalue, G_TYPE_VARIANT);
529 g_value_set_variant (out_gvalue, value);
536 * g_dbus_gvalue_to_gvariant:
537 * @gvalue: A #GValue to convert to a #GVariant
538 * @type: A #GVariantType
540 * Converts a #GValue to a #GVariant of the type indicated by the @type
543 * The conversion is using the following rules:
545 * - #G_TYPE_STRING: 's', 'o', 'g' or 'ay'
546 * - #G_TYPE_STRV: 'as', 'ao' or 'aay'
547 * - #G_TYPE_BOOLEAN: 'b'
548 * - #G_TYPE_UCHAR: 'y'
549 * - #G_TYPE_INT: 'i', 'n'
550 * - #G_TYPE_UINT: 'u', 'q'
551 * - #G_TYPE_INT64 'x'
552 * - #G_TYPE_UINT64: 't'
553 * - #G_TYPE_DOUBLE: 'd'
554 * - #G_TYPE_VARIANT: Any #GVariantType
556 * This can fail if e.g. @gvalue is of type #G_TYPE_STRING and @type
557 * is ['i'][G-VARIANT-TYPE-INT32:CAPS]. It will also fail for any #GType
558 * (including e.g. #G_TYPE_OBJECT and #G_TYPE_BOXED derived-types) not
559 * in the table above.
561 * Note that if @gvalue is of type #G_TYPE_VARIANT and its value is
562 * %NULL, the empty #GVariant instance (never %NULL) for @type is
563 * returned (e.g. 0 for scalar types, the empty string for string types,
564 * '/' for object path types, the empty array for any array type and so on).
566 * See the g_dbus_gvariant_to_gvalue() function for how to convert a
567 * #GVariant to a #GValue.
569 * Returns: (transfer full): A #GVariant (never floating) of
570 * #GVariantType @type holding the data from @gvalue or an empty #GVariant
571 * in case of failure. Free with g_variant_unref().
576 g_dbus_gvalue_to_gvariant (const GValue *gvalue,
577 const GVariantType *type)
581 const gchar * const *as;
582 const gchar *empty_strv[1] = {NULL};
584 g_return_val_if_fail (gvalue != NULL, NULL);
585 g_return_val_if_fail (type != NULL, NULL);
589 /* @type can easily be e.g. "s" with the GValue holding a GVariant - for example this
590 * can happen when using the org.gtk.GDBus.C.ForceGVariant annotation with the
591 * gdbus-codegen(1) tool.
593 if (G_VALUE_TYPE (gvalue) == G_TYPE_VARIANT)
595 ret = g_value_dup_variant (gvalue);
599 switch (g_variant_type_peek_string (type)[0])
601 case G_VARIANT_CLASS_BOOLEAN:
602 ret = g_variant_ref_sink (g_variant_new_boolean (g_value_get_boolean (gvalue)));
605 case G_VARIANT_CLASS_BYTE:
606 ret = g_variant_ref_sink (g_variant_new_byte (g_value_get_uchar (gvalue)));
609 case G_VARIANT_CLASS_INT16:
610 ret = g_variant_ref_sink (g_variant_new_int16 (g_value_get_int (gvalue)));
613 case G_VARIANT_CLASS_UINT16:
614 ret = g_variant_ref_sink (g_variant_new_uint16 (g_value_get_uint (gvalue)));
617 case G_VARIANT_CLASS_INT32:
618 ret = g_variant_ref_sink (g_variant_new_int32 (g_value_get_int (gvalue)));
621 case G_VARIANT_CLASS_UINT32:
622 ret = g_variant_ref_sink (g_variant_new_uint32 (g_value_get_uint (gvalue)));
625 case G_VARIANT_CLASS_INT64:
626 ret = g_variant_ref_sink (g_variant_new_int64 (g_value_get_int64 (gvalue)));
629 case G_VARIANT_CLASS_UINT64:
630 ret = g_variant_ref_sink (g_variant_new_uint64 (g_value_get_uint64 (gvalue)));
633 case G_VARIANT_CLASS_FLOAT:
634 ret = g_variant_ref_sink (g_variant_new_float (g_value_get_float (gvalue)));
637 case G_VARIANT_CLASS_DOUBLE:
638 ret = g_variant_ref_sink (g_variant_new_double (g_value_get_double (gvalue)));
641 case G_VARIANT_CLASS_STRING:
642 s = g_value_get_string (gvalue);
645 ret = g_variant_ref_sink (g_variant_new_string (s));
648 case G_VARIANT_CLASS_OBJECT_PATH:
649 s = g_value_get_string (gvalue);
652 ret = g_variant_ref_sink (g_variant_new_object_path (s));
655 case G_VARIANT_CLASS_SIGNATURE:
656 s = g_value_get_string (gvalue);
659 ret = g_variant_ref_sink (g_variant_new_signature (s));
662 case G_VARIANT_CLASS_ARRAY:
663 switch (g_variant_type_peek_string (type)[1])
665 case G_VARIANT_CLASS_BYTE:
666 s = g_value_get_string (gvalue);
669 ret = g_variant_ref_sink (g_variant_new_bytestring (s));
672 case G_VARIANT_CLASS_STRING:
673 as = g_value_get_boxed (gvalue);
676 ret = g_variant_ref_sink (g_variant_new_strv (as, -1));
679 case G_VARIANT_CLASS_OBJECT_PATH:
680 as = g_value_get_boxed (gvalue);
683 ret = g_variant_ref_sink (g_variant_new_objv (as, -1));
686 case G_VARIANT_CLASS_ARRAY:
687 switch (g_variant_type_peek_string (type)[2])
689 case G_VARIANT_CLASS_BYTE:
690 as = g_value_get_boxed (gvalue);
693 ret = g_variant_ref_sink (g_variant_new_bytestring_array (as, -1));
697 ret = g_value_dup_variant (gvalue);
703 ret = g_value_dup_variant (gvalue);
708 case G_VARIANT_CLASS_HANDLE:
709 case G_VARIANT_CLASS_VARIANT:
710 case G_VARIANT_CLASS_MAYBE:
711 case G_VARIANT_CLASS_TUPLE:
712 case G_VARIANT_CLASS_DICT_ENTRY:
713 ret = g_value_dup_variant (gvalue);
718 /* Could be that the GValue is holding a NULL GVariant - in that case,
719 * we return an "empty" GVariant instead of a NULL GVariant
723 GVariant *untrusted_empty;
724 untrusted_empty = g_variant_new_from_data (type, NULL, 0, FALSE, NULL, NULL);
725 ret = g_variant_take_ref (g_variant_get_normal_form (untrusted_empty));
726 g_variant_unref (untrusted_empty);
729 g_assert (!g_variant_is_floating (ret));
735 * g_dbus_escape_object_path_bytestring:
736 * @bytes: (array zero-terminated=1) (element-type guint8): the string of bytes to escape
738 * Escapes @bytes for use in a D-Bus object path component.
739 * @bytes is an array of zero or more nonzero bytes in an
740 * unspecified encoding, followed by a single zero byte.
742 * The escaping method consists of replacing all non-alphanumeric
743 * characters (see g_ascii_isalnum()) with their hexadecimal value
744 * preceded by an underscore (`_`). For example:
745 * `foo.bar.baz` will become `foo_2ebar_2ebaz`.
747 * This method is appropriate to use when the input is nearly
748 * a valid object path component but is not when your input
749 * is far from being a valid object path component.
750 * Other escaping algorithms are also valid to use with
751 * D-Bus object paths.
753 * This can be reversed with g_dbus_unescape_object_path().
755 * Returns: an escaped version of @bytes. Free with g_free().
761 g_dbus_escape_object_path_bytestring (const guint8 *bytes)
766 g_return_val_if_fail (bytes != NULL, NULL);
769 return g_strdup ("_");
771 escaped = g_string_new (NULL);
772 for (p = bytes; *p; p++)
774 if (g_ascii_isalnum (*p))
775 g_string_append_c (escaped, *p);
777 g_string_append_printf (escaped, "_%02x", *p);
780 return g_string_free (escaped, FALSE);
784 * g_dbus_escape_object_path:
785 * @s: the string to escape
787 * This is a language binding friendly version of g_dbus_escape_object_path_bytestring().
789 * Returns: an escaped version of @s. Free with g_free().
794 g_dbus_escape_object_path (const gchar *s)
796 return (gchar *) g_dbus_escape_object_path_bytestring ((const guint8 *) s);
800 * g_dbus_unescape_object_path:
801 * @s: the string to unescape
803 * Unescapes an string that was previously escaped with
804 * g_dbus_escape_object_path(). If the string is in a format that could
805 * not have been returned by g_dbus_escape_object_path(), this function
808 * Encoding alphanumeric characters which do not need to be
809 * encoded is not allowed (e.g `_63` is not valid, the string
810 * should contain `c` instead).
812 * Returns: (array zero-terminated=1) (element-type guint8) (nullable): an
813 * unescaped version of @s, or %NULL if @s is not a string returned
814 * from g_dbus_escape_object_path(). Free with g_free().
819 g_dbus_unescape_object_path (const gchar *s)
824 g_return_val_if_fail (s != NULL, NULL);
826 if (g_str_equal (s, "_"))
827 return (guint8 *) g_strdup ("");
829 unescaped = g_string_new (NULL);
834 if (g_ascii_isalnum (*p))
836 g_string_append_c (unescaped, *p);
838 else if (*p == '_' &&
839 ((hi = g_ascii_xdigit_value (p[1])) >= 0) &&
840 ((lo = g_ascii_xdigit_value (p[2])) >= 0) &&
841 (hi || lo) && /* \0 is not allowed */
842 !g_ascii_isalnum ((hi << 4) | lo)) /* alnums must not be encoded */
844 g_string_append_c (unescaped, (hi << 4) | lo);
849 /* the string was not encoded correctly */
850 g_string_free (unescaped, TRUE);
855 return (guint8 *) g_string_free (unescaped, FALSE);