1 /* GLib testing framework examples and tests
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 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, write to the
17 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18 * Boston, MA 02111-1307, USA.
20 * Author: David Zeuthen <davidz@redhat.com>
28 #include <dbus/dbus.h>
30 /* ---------------------------------------------------------------------------------------------------- */
33 hexdump (const guchar *str, gsize len)
35 const guchar *data = (const guchar *) str;
38 for (n = 0; n < len; n += 16)
40 g_printerr ("%04x: ", n);
42 for (m = n; m < n + 16; m++)
44 if (m > n && (m%4) == 0)
47 g_printerr ("%02x ", data[m]);
54 for (m = n; m < len && m < n + 16; m++)
55 g_printerr ("%c", g_ascii_isprint (data[m]) ? data[m] : '.');
61 /* ---------------------------------------------------------------------------------------------------- */
64 append_gv_to_dbus_iter (DBusMessageIter *iter,
68 const GVariantType *type;
70 type = g_variant_get_type (value);
71 if (g_variant_type_equal (type, G_VARIANT_TYPE_BOOLEAN))
73 dbus_bool_t v = g_variant_get_boolean (value);
74 dbus_message_iter_append_basic (iter, DBUS_TYPE_BOOLEAN, &v);
76 else if (g_variant_type_equal (type, G_VARIANT_TYPE_BYTE))
78 guint8 v = g_variant_get_byte (value);
79 dbus_message_iter_append_basic (iter, DBUS_TYPE_BYTE, &v);
81 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT16))
83 gint16 v = g_variant_get_int16 (value);
84 dbus_message_iter_append_basic (iter, DBUS_TYPE_INT16, &v);
86 else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT16))
88 guint16 v = g_variant_get_uint16 (value);
89 dbus_message_iter_append_basic (iter, DBUS_TYPE_UINT16, &v);
91 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32))
93 gint32 v = g_variant_get_int32 (value);
94 dbus_message_iter_append_basic (iter, DBUS_TYPE_INT32, &v);
96 else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT32))
98 guint32 v = g_variant_get_uint32 (value);
99 dbus_message_iter_append_basic (iter, DBUS_TYPE_UINT32, &v);
101 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT64))
103 gint64 v = g_variant_get_int64 (value);
104 dbus_message_iter_append_basic (iter, DBUS_TYPE_INT64, &v);
106 else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT64))
108 guint64 v = g_variant_get_uint64 (value);
109 dbus_message_iter_append_basic (iter, DBUS_TYPE_UINT64, &v);
111 else if (g_variant_type_equal (type, G_VARIANT_TYPE_DOUBLE))
113 gdouble v = g_variant_get_double (value);
114 dbus_message_iter_append_basic (iter, DBUS_TYPE_DOUBLE, &v);
116 else if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING))
118 const gchar *v = g_variant_get_string (value, NULL);
119 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &v);
121 else if (g_variant_type_equal (type, G_VARIANT_TYPE_OBJECT_PATH))
123 const gchar *v = g_variant_get_string (value, NULL);
124 dbus_message_iter_append_basic (iter, DBUS_TYPE_OBJECT_PATH, &v);
126 else if (g_variant_type_equal (type, G_VARIANT_TYPE_SIGNATURE))
128 const gchar *v = g_variant_get_string (value, NULL);
129 dbus_message_iter_append_basic (iter, DBUS_TYPE_SIGNATURE, &v);
131 else if (g_variant_type_is_variant (type))
136 child = g_variant_get_child_value (value, 0);
137 dbus_message_iter_open_container (iter, DBUS_TYPE_VARIANT,
138 g_variant_get_type_string (child),
140 if (!append_gv_to_dbus_iter (&sub, child, error))
142 g_variant_unref (child);
145 dbus_message_iter_close_container (iter, &sub);
146 g_variant_unref (child);
148 else if (g_variant_type_is_array (type))
150 DBusMessageIter dbus_iter;
151 const gchar *type_string;
152 GVariantIter gv_iter;
155 type_string = g_variant_get_type_string (value);
156 type_string++; /* skip the 'a' */
158 dbus_message_iter_open_container (iter, DBUS_TYPE_ARRAY,
159 type_string, &dbus_iter);
160 g_variant_iter_init (&gv_iter, value);
162 while ((item = g_variant_iter_next_value (&gv_iter)))
164 if (!append_gv_to_dbus_iter (&dbus_iter, item, error))
170 dbus_message_iter_close_container (iter, &dbus_iter);
172 else if (g_variant_type_is_tuple (type))
174 DBusMessageIter dbus_iter;
175 GVariantIter gv_iter;
178 dbus_message_iter_open_container (iter, DBUS_TYPE_STRUCT,
180 g_variant_iter_init (&gv_iter, value);
182 while ((item = g_variant_iter_next_value (&gv_iter)))
184 if (!append_gv_to_dbus_iter (&dbus_iter, item, error))
188 dbus_message_iter_close_container (iter, &dbus_iter);
190 else if (g_variant_type_is_dict_entry (type))
192 DBusMessageIter dbus_iter;
195 dbus_message_iter_open_container (iter, DBUS_TYPE_DICT_ENTRY,
197 key = g_variant_get_child_value (value, 0);
198 if (!append_gv_to_dbus_iter (&dbus_iter, key, error))
200 g_variant_unref (key);
203 g_variant_unref (key);
205 val = g_variant_get_child_value (value, 1);
206 if (!append_gv_to_dbus_iter (&dbus_iter, val, error))
208 g_variant_unref (val);
211 g_variant_unref (val);
213 dbus_message_iter_close_container (iter, &dbus_iter);
219 G_IO_ERROR_INVALID_ARGUMENT,
220 "Error serializing GVariant with type-string '%s' to a D-Bus message",
221 g_variant_get_type_string (value));
232 append_gv_to_dbus_message (DBusMessage *message,
243 DBusMessageIter iter;
244 GVariantIter gv_iter;
247 dbus_message_iter_init_append (message, &iter);
249 g_variant_iter_init (&gv_iter, value);
251 while ((item = g_variant_iter_next_value (&gv_iter)))
253 if (!append_gv_to_dbus_iter (&iter, item, error))
255 g_prefix_error (error,
256 "Error encoding in-arg %d: ",
271 print_gv_dbus_message (GVariant *value)
273 DBusMessage *message;
278 message = dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_CALL);
279 dbus_message_set_serial (message, 0x41);
280 dbus_message_set_path (message, "/foo/bar");
281 dbus_message_set_member (message, "Member");
284 if (!append_gv_to_dbus_message (message, value, &error))
286 g_printerr ("Error printing GVariant as DBusMessage: %s", error->message);
287 g_error_free (error);
291 dbus_message_marshal (message, &blob, &blob_len);
293 hexdump ((guchar *) blob, blob_len);
295 dbus_message_unref (message);
298 /* ---------------------------------------------------------------------------------------------------- */
301 dbus_1_message_append (GString *s,
303 DBusMessageIter *iter)
308 g_string_append_printf (s, "%*s", indent, "");
310 arg_type = dbus_message_iter_get_arg_type (iter);
313 case DBUS_TYPE_BOOLEAN:
316 dbus_message_iter_get_basic (iter, &value);
317 g_string_append_printf (s, "bool: %s\n", value ? "true" : "false");
324 dbus_message_iter_get_basic (iter, &value);
325 g_string_append_printf (s, "byte: 0x%02x\n", (guint) value);
329 case DBUS_TYPE_INT16:
332 dbus_message_iter_get_basic (iter, &value);
333 g_string_append_printf (s, "int16: %" G_GINT16_FORMAT "\n", value);
337 case DBUS_TYPE_UINT16:
340 dbus_message_iter_get_basic (iter, &value);
341 g_string_append_printf (s, "uint16: %" G_GUINT16_FORMAT "\n", value);
345 case DBUS_TYPE_INT32:
348 dbus_message_iter_get_basic (iter, &value);
349 g_string_append_printf (s, "int32: %" G_GINT32_FORMAT "\n", value);
353 case DBUS_TYPE_UINT32:
356 dbus_message_iter_get_basic (iter, &value);
357 g_string_append_printf (s, "uint32: %" G_GUINT32_FORMAT "\n", value);
361 case DBUS_TYPE_INT64:
364 dbus_message_iter_get_basic (iter, &value);
365 g_string_append_printf (s, "int64: %" G_GINT64_FORMAT "\n", value);
369 case DBUS_TYPE_UINT64:
372 dbus_message_iter_get_basic (iter, &value);
373 g_string_append_printf (s, "uint64: %" G_GUINT64_FORMAT "\n", value);
377 case DBUS_TYPE_DOUBLE:
380 dbus_message_iter_get_basic (iter, &value);
381 g_string_append_printf (s, "double: %f\n", value);
385 case DBUS_TYPE_STRING:
388 dbus_message_iter_get_basic (iter, &value);
389 g_string_append_printf (s, "string: '%s'\n", value);
393 case DBUS_TYPE_OBJECT_PATH:
396 dbus_message_iter_get_basic (iter, &value);
397 g_string_append_printf (s, "object_path: '%s'\n", value);
401 case DBUS_TYPE_SIGNATURE:
404 dbus_message_iter_get_basic (iter, &value);
405 g_string_append_printf (s, "signature: '%s'\n", value);
409 #ifdef DBUS_TYPE_UNIX_FD
410 case DBUS_TYPE_UNIX_FD:
412 /* unfortunately there's currently no way to get just the
413 * protocol value, since dbus_message_iter_get_basic() wants
414 * to be 'helpful' and dup the fd for the user...
416 g_string_append (s, "unix-fd: (not extracted)\n");
421 case DBUS_TYPE_VARIANT:
422 g_string_append_printf (s, "variant:\n");
423 dbus_message_iter_recurse (iter, &sub);
424 while (dbus_message_iter_get_arg_type (&sub))
426 dbus_1_message_append (s, indent + 2, &sub);
427 dbus_message_iter_next (&sub);
431 case DBUS_TYPE_ARRAY:
432 g_string_append_printf (s, "array:\n");
433 dbus_message_iter_recurse (iter, &sub);
434 while (dbus_message_iter_get_arg_type (&sub))
436 dbus_1_message_append (s, indent + 2, &sub);
437 dbus_message_iter_next (&sub);
441 case DBUS_TYPE_STRUCT:
442 g_string_append_printf (s, "struct:\n");
443 dbus_message_iter_recurse (iter, &sub);
444 while (dbus_message_iter_get_arg_type (&sub))
446 dbus_1_message_append (s, indent + 2, &sub);
447 dbus_message_iter_next (&sub);
451 case DBUS_TYPE_DICT_ENTRY:
452 g_string_append_printf (s, "dict_entry:\n");
453 dbus_message_iter_recurse (iter, &sub);
454 while (dbus_message_iter_get_arg_type (&sub))
456 dbus_1_message_append (s, indent + 2, &sub);
457 dbus_message_iter_next (&sub);
462 g_printerr ("Error serializing D-Bus message to GVariant. Unsupported arg type '%c' (%d)",
465 g_assert_not_reached ();
471 dbus_1_message_print (DBusMessage *message)
475 DBusMessageIter iter;
477 s = g_string_new (NULL);
479 dbus_message_iter_init (message, &iter);
480 while (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_INVALID)
482 g_string_append_printf (s, "value %d: ", n);
483 dbus_1_message_append (s, 2, &iter);
484 dbus_message_iter_next (&iter);
488 return g_string_free (s, FALSE);
491 /* ---------------------------------------------------------------------------------------------------- */
494 get_body_signature (GVariant *value)
506 s = g_variant_get_type_string (value);
510 ret = g_strndup (s + 1, len - 2);
517 check_serialization (GVariant *value,
518 const gchar *expected_dbus_1_output)
522 DBusMessage *dbus_1_message;
523 GDBusMessage *message;
524 GDBusMessage *recovered_message;
526 DBusError dbus_error;
531 message = g_dbus_message_new ();
532 g_dbus_message_set_body (message, value);
533 g_dbus_message_set_message_type (message, G_DBUS_MESSAGE_TYPE_METHOD_CALL);
534 g_dbus_message_set_serial (message, 0x41);
535 s = get_body_signature (value);
536 g_dbus_message_set_header (message, G_DBUS_MESSAGE_HEADER_FIELD_PATH, g_variant_new_object_path ("/foo/bar"));
537 g_dbus_message_set_header (message, G_DBUS_MESSAGE_HEADER_FIELD_MEMBER, g_variant_new_string ("Member"));
538 g_dbus_message_set_header (message, G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE, g_variant_new_signature (s));
541 /* First check that the serialization to the D-Bus wire format is correct - do this for both byte orders */
542 for (n = 0; n < 2; n++)
544 GDBusMessageByteOrder byte_order;
548 byte_order = G_DBUS_MESSAGE_BYTE_ORDER_BIG_ENDIAN;
551 byte_order = G_DBUS_MESSAGE_BYTE_ORDER_LITTLE_ENDIAN;
554 g_assert_not_reached ();
557 g_dbus_message_set_byte_order (message, byte_order);
560 blob = g_dbus_message_to_blob (message,
562 G_DBUS_CAPABILITY_FLAGS_NONE,
564 g_assert_no_error (error);
565 g_assert (blob != NULL);
569 case G_DBUS_MESSAGE_BYTE_ORDER_BIG_ENDIAN:
570 g_assert_cmpint (blob[0], ==, 'B');
572 case G_DBUS_MESSAGE_BYTE_ORDER_LITTLE_ENDIAN:
573 g_assert_cmpint (blob[0], ==, 'l');
577 dbus_error_init (&dbus_error);
578 dbus_1_message = dbus_message_demarshal ((char *) blob, blob_size, &dbus_error);
579 if (dbus_error_is_set (&dbus_error))
581 g_printerr ("Error calling dbus_message_demarshal() on this blob: %s: %s\n",
584 hexdump (blob, blob_size);
585 dbus_error_free (&dbus_error);
587 s = g_variant_print (value, TRUE);
588 g_printerr ("\nThe blob was generated from the following GVariant value:\n%s\n\n", s);
591 g_printerr ("If the blob was encoded using DBusMessageIter, the payload would have been:\n");
592 print_gv_dbus_message (value);
594 g_assert_not_reached ();
597 s = dbus_1_message_print (dbus_1_message);
598 dbus_message_unref (dbus_1_message);
600 g_assert_cmpstr (s, ==, expected_dbus_1_output);
603 /* Then serialize back and check that the body is identical */
606 recovered_message = g_dbus_message_new_from_blob (blob,
608 G_DBUS_CAPABILITY_FLAGS_NONE,
610 g_assert_no_error (error);
611 g_assert (recovered_message != NULL);
615 g_assert (g_dbus_message_get_body (recovered_message) == NULL);
619 g_assert (g_dbus_message_get_body (recovered_message) != NULL);
620 if (!g_variant_equal (g_dbus_message_get_body (recovered_message), value))
622 s = g_variant_print (g_dbus_message_get_body (recovered_message), TRUE);
623 s1 = g_variant_print (value, TRUE);
624 g_printerr ("Recovered value:\n%s\ndoes not match given value\n%s\n",
629 g_assert_not_reached ();
632 g_object_unref (recovered_message);
635 g_object_unref (message);
639 message_serialize_basic (void)
641 check_serialization (NULL, "");
643 check_serialization (g_variant_new ("(sogybnqiuxtd)",
653 -G_GINT64_CONSTANT(2)<<34,
654 G_GUINT64_CONSTANT(0xffffffffffffffff),
656 "value 0: string: 'this is a string'\n"
657 "value 1: object_path: '/this/is/a/path'\n"
658 "value 2: signature: 'sad'\n"
659 "value 3: byte: 0x2a\n"
660 "value 4: bool: true\n"
661 "value 5: int16: -42\n"
662 "value 6: uint16: 60000\n"
663 "value 7: int32: -44\n"
664 "value 8: uint32: 100000\n"
665 "value 9: int64: -34359738368\n"
666 "value 10: uint64: 18446744073709551615\n"
667 "value 11: double: 42.500000\n");
670 /* ---------------------------------------------------------------------------------------------------- */
673 message_serialize_complex (void)
680 value = g_variant_parse (G_VARIANT_TYPE ("(aia{ss})"),
681 "([1, 2, 3], {'one': 'white', 'two': 'black'})",
683 g_assert_no_error (error);
684 g_assert (value != NULL);
685 check_serialization (value,
696 " string: 'black'\n");
698 value = g_variant_parse (G_VARIANT_TYPE ("(sa{sv}as)"),
699 "('01234567890123456', {}, ['Something'])",
701 g_assert_no_error (error);
702 g_assert (value != NULL);
703 check_serialization (value,
704 "value 0: string: '01234567890123456'\n"
707 " string: 'Something'\n");
709 /* https://bugzilla.gnome.org/show_bug.cgi?id=621838 */
710 check_serialization (g_variant_new_parsed ("(@aay [], {'cwd': <'/home/davidz/Hacking/glib/gio/tests'>})"),
716 " string: '/home/davidz/Hacking/glib/gio/tests'\n");
718 #ifdef DBUS_TYPE_UNIX_FD
719 value = g_variant_parse (G_VARIANT_TYPE ("(hah)"),
722 g_assert_no_error (error);
723 g_assert (value != NULL);
724 /* about (not extracted), see comment in DBUS_TYPE_UNIX_FD case in
725 * dbus_1_message_append() above.
727 check_serialization (value,
728 "value 0: unix-fd: (not extracted)\n"
730 " unix-fd: (not extracted)\n"
731 " unix-fd: (not extracted)\n");
736 /* ---------------------------------------------------------------------------------------------------- */
745 gsize slen = strlen (before) + 1;
747 g_assert_cmpuint (strlen (before), ==, strlen (after));
748 g_assert_cmpuint (len, >=, slen);
750 for (i = 0; i < (len - slen + 1); i++)
752 if (memcmp (blob + i, before, slen) == 0)
753 memcpy (blob + i, after, slen);
758 message_serialize_invalid (void)
762 /* Other things we could check (note that GDBus _does_ check for all
763 * these things - we just don't have test-suit coverage for it)
765 * - array exceeding 64 MiB (2^26 bytes) - unfortunately libdbus-1 checks
768 * process 19620: arguments to dbus_message_iter_append_fixed_array() were incorrect,
769 * assertion "n_elements <= DBUS_MAXIMUM_ARRAY_LENGTH / _dbus_type_get_alignment (element_type)"
770 * failed in file dbus-message.c line 2344.
771 * This is normally a bug in some application using the D-Bus library.
772 * D-Bus not built with -rdynamic so unable to print a backtrace
773 * Aborted (core dumped)
775 * - message exceeding 128 MiB (2^27 bytes)
777 * - endianness, message type, flags, protocol version
780 for (n = 0; n < 3; n++)
782 GDBusMessage *message;
784 DBusMessage *dbus_message;
787 /* these are in pairs with matching length */
788 const gchar *valid_utf8_str = "this is valid...";
789 const gchar *invalid_utf8_str = "this is invalid\xff";
790 const gchar *valid_signature = "a{sv}a{sv}a{sv}aiai";
791 const gchar *invalid_signature = "not valid signature";
792 const gchar *valid_object_path = "/this/is/a/valid/dbus/object/path";
793 const gchar *invalid_object_path = "/this/is/not a valid object path!";
795 dbus_message = dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_CALL);
796 dbus_message_set_serial (dbus_message, 0x41);
797 dbus_message_set_path (dbus_message, "/foo/bar");
798 dbus_message_set_member (dbus_message, "Member");
803 dbus_message_append_args (dbus_message,
804 DBUS_TYPE_STRING, &valid_utf8_str,
809 /* invalid object path */
810 dbus_message_append_args (dbus_message,
811 DBUS_TYPE_OBJECT_PATH, &valid_object_path,
816 /* invalid signature */
817 dbus_message_append_args (dbus_message,
818 DBUS_TYPE_SIGNATURE, &valid_signature,
823 g_assert_not_reached ();
826 dbus_message_marshal (dbus_message, &blob, &blob_len);
827 /* hack up the message to be invalid by replacing each valid string
828 * with its invalid counterpart */
829 replace (blob, blob_len, valid_utf8_str, invalid_utf8_str);
830 replace (blob, blob_len, valid_object_path, invalid_object_path);
831 replace (blob, blob_len, valid_signature, invalid_signature);
834 message = g_dbus_message_new_from_blob ((guchar *) blob,
836 G_DBUS_CAPABILITY_FLAGS_NONE,
838 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
839 g_error_free (error);
840 g_assert (message == NULL);
847 /* ---------------------------------------------------------------------------------------------------- */
850 message_serialize_header_checks (void)
852 GDBusMessage *message;
859 * check we can't serialize messages with INVALID type
861 message = g_dbus_message_new ();
863 blob = g_dbus_message_to_blob (message, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error);
864 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
865 g_assert_cmpstr (error->message, ==, "Cannot serialize message: type is INVALID");
866 g_error_free (error);
867 g_assert (blob == NULL);
868 g_object_unref (message);
871 * check we can't serialize signal messages with INTERFACE, PATH or MEMBER unset / set to reserved value
873 message = g_dbus_message_new_signal ("/the/path", "The.Interface", "TheMember");
875 /* interface NULL => error */
876 g_dbus_message_set_interface (message, NULL);
878 blob = g_dbus_message_to_blob (message, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error);
879 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
880 g_assert_cmpstr (error->message, ==, "Cannot serialize message: SIGNAL message: PATH, INTERFACE or MEMBER header field is missing");
881 g_error_free (error);
882 g_assert (blob == NULL);
883 /* interface reserved value => error */
884 g_dbus_message_set_interface (message, "org.freedesktop.DBus.Local");
886 blob = g_dbus_message_to_blob (message, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error);
887 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
888 g_assert_cmpstr (error->message, ==, "Cannot serialize message: SIGNAL message: The INTERFACE header field is using the reserved value org.freedesktop.DBus.Local");
889 g_error_free (error);
890 g_assert (blob == NULL);
891 /* reset interface */
892 g_dbus_message_set_interface (message, "The.Interface");
894 /* path NULL => error */
895 g_dbus_message_set_path (message, NULL);
897 blob = g_dbus_message_to_blob (message, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error);
898 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
899 g_assert_cmpstr (error->message, ==, "Cannot serialize message: SIGNAL message: PATH, INTERFACE or MEMBER header field is missing");
900 g_error_free (error);
901 g_assert (blob == NULL);
902 /* path reserved value => error */
903 g_dbus_message_set_path (message, "/org/freedesktop/DBus/Local");
905 blob = g_dbus_message_to_blob (message, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error);
906 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
907 g_assert_cmpstr (error->message, ==, "Cannot serialize message: SIGNAL message: The PATH header field is using the reserved value /org/freedesktop/DBus/Local");
908 g_error_free (error);
909 g_assert (blob == NULL);
911 g_dbus_message_set_path (message, "/the/path");
913 /* member NULL => error */
914 g_dbus_message_set_member (message, NULL);
916 blob = g_dbus_message_to_blob (message, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error);
917 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
918 g_assert_cmpstr (error->message, ==, "Cannot serialize message: SIGNAL message: PATH, INTERFACE or MEMBER header field is missing");
919 g_error_free (error);
920 g_assert (blob == NULL);
922 g_dbus_message_set_member (message, "TheMember");
925 g_object_unref (message);
928 * check that we can't serialize method call messages with PATH or MEMBER unset
930 message = g_dbus_message_new_method_call (NULL, "/the/path", NULL, "TheMember");
932 /* path NULL => error */
933 g_dbus_message_set_path (message, NULL);
935 blob = g_dbus_message_to_blob (message, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error);
936 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
937 g_assert_cmpstr (error->message, ==, "Cannot serialize message: METHOD_CALL message: PATH or MEMBER header field is missing");
938 g_error_free (error);
939 g_assert (blob == NULL);
941 g_dbus_message_set_path (message, "/the/path");
943 /* member NULL => error */
944 g_dbus_message_set_member (message, NULL);
946 blob = g_dbus_message_to_blob (message, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error);
947 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
948 g_assert_cmpstr (error->message, ==, "Cannot serialize message: METHOD_CALL message: PATH or MEMBER header field is missing");
949 g_error_free (error);
950 g_assert (blob == NULL);
952 g_dbus_message_set_member (message, "TheMember");
955 g_object_unref (message);
958 * check that we can't serialize method reply messages with REPLY_SERIAL unset
960 message = g_dbus_message_new_method_call (NULL, "/the/path", NULL, "TheMember");
961 g_dbus_message_set_serial (message, 42);
963 reply = g_dbus_message_new_method_reply (message);
964 g_assert_cmpint (g_dbus_message_get_reply_serial (reply), ==, 42);
965 g_dbus_message_set_header (reply, G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL, NULL);
967 blob = g_dbus_message_to_blob (reply, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error);
968 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
969 g_assert_cmpstr (error->message, ==, "Cannot serialize message: METHOD_RETURN message: REPLY_SERIAL header field is missing");
970 g_error_free (error);
971 g_assert (blob == NULL);
972 g_object_unref (reply);
973 /* method error - first nuke ERROR_NAME, then REPLY_SERIAL */
974 reply = g_dbus_message_new_method_error (message, "Some.Error.Name", "the message");
975 g_assert_cmpint (g_dbus_message_get_reply_serial (reply), ==, 42);
976 /* nuke ERROR_NAME */
977 g_dbus_message_set_error_name (reply, NULL);
979 blob = g_dbus_message_to_blob (reply, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error);
980 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
981 g_assert_cmpstr (error->message, ==, "Cannot serialize message: ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing");
982 g_error_free (error);
983 g_assert (blob == NULL);
984 /* reset ERROR_NAME */
985 g_dbus_message_set_error_name (reply, "Some.Error.Name");
986 /* nuke REPLY_SERIAL */
987 g_dbus_message_set_header (reply, G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL, NULL);
989 blob = g_dbus_message_to_blob (reply, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error);
990 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
991 g_assert_cmpstr (error->message, ==, "Cannot serialize message: ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing");
992 g_error_free (error);
993 g_assert (blob == NULL);
994 g_object_unref (reply);
995 g_object_unref (message);
998 /* ---------------------------------------------------------------------------------------------------- */
1001 message_parse_empty_arrays_of_arrays (void)
1004 GError *error = NULL;
1006 g_test_bug ("673612");
1007 /* These three-element array of empty arrays were previously read back as a
1008 * two-element array of empty arrays, due to sometimes erroneously skipping
1009 * four bytes to align for the eight-byte-aligned grandchild types (x and
1012 body = g_variant_parse (G_VARIANT_TYPE ("(aaax)"),
1013 "([@aax [], [], []],)", NULL, NULL, &error);
1014 g_assert_no_error (error);
1015 check_serialization (body,
1021 body = g_variant_parse (G_VARIANT_TYPE ("(aaa{uu})"),
1022 "([@aa{uu} [], [], []],)", NULL, NULL, &error);
1023 g_assert_no_error (error);
1024 check_serialization (body,
1030 /* Due to the same bug, g_dbus_message_new_from_blob() would fail for this
1031 * message because it would try to read past the end of the string. Hence,
1032 * sending this to an application would make it fall off the bus. */
1033 body = g_variant_parse (G_VARIANT_TYPE ("(a(aa{sv}as))"),
1036 " ([], [])],)", NULL, NULL, &error);
1037 g_assert_no_error (error);
1038 check_serialization (body,
1051 /* ---------------------------------------------------------------------------------------------------- */
1057 setlocale (LC_ALL, "C");
1059 g_test_init (&argc, &argv, NULL);
1060 g_test_bug_base ("https://bugzilla.gnome.org/show_bug.cgi?id=");
1062 g_test_add_func ("/gdbus/message-serialize-basic", message_serialize_basic);
1063 g_test_add_func ("/gdbus/message-serialize-complex", message_serialize_complex);
1064 g_test_add_func ("/gdbus/message-serialize-invalid", message_serialize_invalid);
1065 g_test_add_func ("/gdbus/message-serialize-header-checks", message_serialize_header_checks);
1067 g_test_add_func ("/gdbus/message-parse-empty-arrays-of-arrays",
1068 message_parse_empty_arrays_of_arrays);
1070 return g_test_run();