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.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 <dbus/dbus.h>
28 /* ---------------------------------------------------------------------------------------------------- */
31 hexdump (const guchar
*str
, gsize len
)
33 const guchar
*data
= (const guchar
*) str
;
36 for (n
= 0; n
< len
; n
+= 16)
38 g_printerr ("%04x: ", n
);
40 for (m
= n
; m
< n
+ 16; m
++)
42 if (m
> n
&& (m
%4) == 0)
45 g_printerr ("%02x ", data
[m
]);
52 for (m
= n
; m
< len
&& m
< n
+ 16; m
++)
53 g_printerr ("%c", g_ascii_isprint (data
[m
]) ? data
[m
] : '.');
59 /* ---------------------------------------------------------------------------------------------------- */
62 append_gv_to_dbus_iter (DBusMessageIter
*iter
,
66 const GVariantType
*type
;
68 type
= g_variant_get_type (value
);
69 if (g_variant_type_equal (type
, G_VARIANT_TYPE_BOOLEAN
))
71 dbus_bool_t v
= g_variant_get_boolean (value
);
72 dbus_message_iter_append_basic (iter
, DBUS_TYPE_BOOLEAN
, &v
);
74 else if (g_variant_type_equal (type
, G_VARIANT_TYPE_BYTE
))
76 guint8 v
= g_variant_get_byte (value
);
77 dbus_message_iter_append_basic (iter
, DBUS_TYPE_BYTE
, &v
);
79 else if (g_variant_type_equal (type
, G_VARIANT_TYPE_INT16
))
81 gint16 v
= g_variant_get_int16 (value
);
82 dbus_message_iter_append_basic (iter
, DBUS_TYPE_INT16
, &v
);
84 else if (g_variant_type_equal (type
, G_VARIANT_TYPE_UINT16
))
86 guint16 v
= g_variant_get_uint16 (value
);
87 dbus_message_iter_append_basic (iter
, DBUS_TYPE_UINT16
, &v
);
89 else if (g_variant_type_equal (type
, G_VARIANT_TYPE_INT32
))
91 gint32 v
= g_variant_get_int32 (value
);
92 dbus_message_iter_append_basic (iter
, DBUS_TYPE_INT32
, &v
);
94 else if (g_variant_type_equal (type
, G_VARIANT_TYPE_UINT32
))
96 guint32 v
= g_variant_get_uint32 (value
);
97 dbus_message_iter_append_basic (iter
, DBUS_TYPE_UINT32
, &v
);
99 else if (g_variant_type_equal (type
, G_VARIANT_TYPE_INT64
))
101 gint64 v
= g_variant_get_int64 (value
);
102 dbus_message_iter_append_basic (iter
, DBUS_TYPE_INT64
, &v
);
104 else if (g_variant_type_equal (type
, G_VARIANT_TYPE_UINT64
))
106 guint64 v
= g_variant_get_uint64 (value
);
107 dbus_message_iter_append_basic (iter
, DBUS_TYPE_UINT64
, &v
);
109 else if (g_variant_type_equal (type
, G_VARIANT_TYPE_DOUBLE
))
111 gdouble v
= g_variant_get_double (value
);
112 dbus_message_iter_append_basic (iter
, DBUS_TYPE_DOUBLE
, &v
);
114 else if (g_variant_type_equal (type
, G_VARIANT_TYPE_STRING
))
116 const gchar
*v
= g_variant_get_string (value
, NULL
);
117 dbus_message_iter_append_basic (iter
, DBUS_TYPE_STRING
, &v
);
119 else if (g_variant_type_equal (type
, G_VARIANT_TYPE_OBJECT_PATH
))
121 const gchar
*v
= g_variant_get_string (value
, NULL
);
122 dbus_message_iter_append_basic (iter
, DBUS_TYPE_OBJECT_PATH
, &v
);
124 else if (g_variant_type_equal (type
, G_VARIANT_TYPE_SIGNATURE
))
126 const gchar
*v
= g_variant_get_string (value
, NULL
);
127 dbus_message_iter_append_basic (iter
, DBUS_TYPE_SIGNATURE
, &v
);
129 else if (g_variant_type_is_variant (type
))
134 child
= g_variant_get_child_value (value
, 0);
135 dbus_message_iter_open_container (iter
, DBUS_TYPE_VARIANT
,
136 g_variant_get_type_string (child
),
138 if (!append_gv_to_dbus_iter (&sub
, child
, error
))
140 g_variant_unref (child
);
143 dbus_message_iter_close_container (iter
, &sub
);
144 g_variant_unref (child
);
146 else if (g_variant_type_is_array (type
))
148 DBusMessageIter dbus_iter
;
149 const gchar
*type_string
;
150 GVariantIter gv_iter
;
153 type_string
= g_variant_get_type_string (value
);
154 type_string
++; /* skip the 'a' */
156 dbus_message_iter_open_container (iter
, DBUS_TYPE_ARRAY
,
157 type_string
, &dbus_iter
);
158 g_variant_iter_init (&gv_iter
, value
);
160 while ((item
= g_variant_iter_next_value (&gv_iter
)))
162 if (!append_gv_to_dbus_iter (&dbus_iter
, item
, error
))
168 dbus_message_iter_close_container (iter
, &dbus_iter
);
170 else if (g_variant_type_is_tuple (type
))
172 DBusMessageIter dbus_iter
;
173 GVariantIter gv_iter
;
176 dbus_message_iter_open_container (iter
, DBUS_TYPE_STRUCT
,
178 g_variant_iter_init (&gv_iter
, value
);
180 while ((item
= g_variant_iter_next_value (&gv_iter
)))
182 if (!append_gv_to_dbus_iter (&dbus_iter
, item
, error
))
186 dbus_message_iter_close_container (iter
, &dbus_iter
);
188 else if (g_variant_type_is_dict_entry (type
))
190 DBusMessageIter dbus_iter
;
193 dbus_message_iter_open_container (iter
, DBUS_TYPE_DICT_ENTRY
,
195 key
= g_variant_get_child_value (value
, 0);
196 if (!append_gv_to_dbus_iter (&dbus_iter
, key
, error
))
198 g_variant_unref (key
);
201 g_variant_unref (key
);
203 val
= g_variant_get_child_value (value
, 1);
204 if (!append_gv_to_dbus_iter (&dbus_iter
, val
, error
))
206 g_variant_unref (val
);
209 g_variant_unref (val
);
211 dbus_message_iter_close_container (iter
, &dbus_iter
);
217 G_IO_ERROR_INVALID_ARGUMENT
,
218 "Error serializing GVariant with type-string '%s' to a D-Bus message",
219 g_variant_get_type_string (value
));
230 append_gv_to_dbus_message (DBusMessage
*message
,
241 DBusMessageIter iter
;
242 GVariantIter gv_iter
;
245 dbus_message_iter_init_append (message
, &iter
);
247 g_variant_iter_init (&gv_iter
, value
);
249 while ((item
= g_variant_iter_next_value (&gv_iter
)))
251 if (!append_gv_to_dbus_iter (&iter
, item
, error
))
253 g_prefix_error (error
,
254 "Error encoding in-arg %d: ",
269 print_gv_dbus_message (GVariant
*value
)
271 DBusMessage
*message
;
276 message
= dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_CALL
);
277 dbus_message_set_serial (message
, 0x41);
278 dbus_message_set_path (message
, "/foo/bar");
279 dbus_message_set_member (message
, "Member");
282 if (!append_gv_to_dbus_message (message
, value
, &error
))
284 g_printerr ("Error printing GVariant as DBusMessage: %s", error
->message
);
285 g_error_free (error
);
289 dbus_message_marshal (message
, &blob
, &blob_len
);
291 hexdump ((guchar
*) blob
, blob_len
);
293 dbus_message_unref (message
);
296 /* ---------------------------------------------------------------------------------------------------- */
299 dbus_1_message_append (GString
*s
,
301 DBusMessageIter
*iter
)
306 g_string_append_printf (s
, "%*s", indent
, "");
308 arg_type
= dbus_message_iter_get_arg_type (iter
);
311 case DBUS_TYPE_BOOLEAN
:
314 dbus_message_iter_get_basic (iter
, &value
);
315 g_string_append_printf (s
, "bool: %s\n", value
? "true" : "false");
322 dbus_message_iter_get_basic (iter
, &value
);
323 g_string_append_printf (s
, "byte: 0x%02x\n", (guint
) value
);
327 case DBUS_TYPE_INT16
:
330 dbus_message_iter_get_basic (iter
, &value
);
331 g_string_append_printf (s
, "int16: %" G_GINT16_FORMAT
"\n", value
);
335 case DBUS_TYPE_UINT16
:
338 dbus_message_iter_get_basic (iter
, &value
);
339 g_string_append_printf (s
, "uint16: %" G_GUINT16_FORMAT
"\n", value
);
343 case DBUS_TYPE_INT32
:
346 dbus_message_iter_get_basic (iter
, &value
);
347 g_string_append_printf (s
, "int32: %" G_GINT32_FORMAT
"\n", value
);
351 case DBUS_TYPE_UINT32
:
354 dbus_message_iter_get_basic (iter
, &value
);
355 g_string_append_printf (s
, "uint32: %" G_GUINT32_FORMAT
"\n", value
);
359 case DBUS_TYPE_INT64
:
362 dbus_message_iter_get_basic (iter
, &value
);
363 g_string_append_printf (s
, "int64: %" G_GINT64_FORMAT
"\n", value
);
367 case DBUS_TYPE_UINT64
:
370 dbus_message_iter_get_basic (iter
, &value
);
371 g_string_append_printf (s
, "uint64: %" G_GUINT64_FORMAT
"\n", value
);
375 case DBUS_TYPE_DOUBLE
:
378 dbus_message_iter_get_basic (iter
, &value
);
379 g_string_append_printf (s
, "double: %f\n", value
);
383 case DBUS_TYPE_STRING
:
386 dbus_message_iter_get_basic (iter
, &value
);
387 g_string_append_printf (s
, "string: '%s'\n", value
);
391 case DBUS_TYPE_OBJECT_PATH
:
394 dbus_message_iter_get_basic (iter
, &value
);
395 g_string_append_printf (s
, "object_path: '%s'\n", value
);
399 case DBUS_TYPE_SIGNATURE
:
402 dbus_message_iter_get_basic (iter
, &value
);
403 g_string_append_printf (s
, "signature: '%s'\n", value
);
407 #ifdef DBUS_TYPE_UNIX_FD
408 case DBUS_TYPE_UNIX_FD
:
410 /* unfortunately there's currently no way to get just the
411 * protocol value, since dbus_message_iter_get_basic() wants
412 * to be 'helpful' and dup the fd for the user...
414 g_string_append (s
, "unix-fd: (not extracted)\n");
419 case DBUS_TYPE_VARIANT
:
420 g_string_append_printf (s
, "variant:\n");
421 dbus_message_iter_recurse (iter
, &sub
);
422 while (dbus_message_iter_get_arg_type (&sub
))
424 dbus_1_message_append (s
, indent
+ 2, &sub
);
425 dbus_message_iter_next (&sub
);
429 case DBUS_TYPE_ARRAY
:
430 g_string_append_printf (s
, "array:\n");
431 dbus_message_iter_recurse (iter
, &sub
);
432 while (dbus_message_iter_get_arg_type (&sub
))
434 dbus_1_message_append (s
, indent
+ 2, &sub
);
435 dbus_message_iter_next (&sub
);
439 case DBUS_TYPE_STRUCT
:
440 g_string_append_printf (s
, "struct:\n");
441 dbus_message_iter_recurse (iter
, &sub
);
442 while (dbus_message_iter_get_arg_type (&sub
))
444 dbus_1_message_append (s
, indent
+ 2, &sub
);
445 dbus_message_iter_next (&sub
);
449 case DBUS_TYPE_DICT_ENTRY
:
450 g_string_append_printf (s
, "dict_entry:\n");
451 dbus_message_iter_recurse (iter
, &sub
);
452 while (dbus_message_iter_get_arg_type (&sub
))
454 dbus_1_message_append (s
, indent
+ 2, &sub
);
455 dbus_message_iter_next (&sub
);
460 g_printerr ("Error serializing D-Bus message to GVariant. Unsupported arg type '%c' (%d)",
463 g_assert_not_reached ();
469 dbus_1_message_print (DBusMessage
*message
)
473 DBusMessageIter iter
;
475 s
= g_string_new (NULL
);
477 dbus_message_iter_init (message
, &iter
);
478 while (dbus_message_iter_get_arg_type (&iter
) != DBUS_TYPE_INVALID
)
480 g_string_append_printf (s
, "value %d: ", n
);
481 dbus_1_message_append (s
, 2, &iter
);
482 dbus_message_iter_next (&iter
);
486 return g_string_free (s
, FALSE
);
489 /* ---------------------------------------------------------------------------------------------------- */
492 get_body_signature (GVariant
*value
)
504 s
= g_variant_get_type_string (value
);
508 ret
= g_strndup (s
+ 1, len
- 2);
514 /* If @value is floating, this assumes ownership. */
516 check_serialization (GVariant
*value
,
517 const gchar
*expected_dbus_1_output
)
521 DBusMessage
*dbus_1_message
;
522 GDBusMessage
*message
;
523 GDBusMessage
*recovered_message
;
525 DBusError dbus_error
;
530 message
= g_dbus_message_new ();
531 g_dbus_message_set_body (message
, value
);
532 g_dbus_message_set_message_type (message
, G_DBUS_MESSAGE_TYPE_METHOD_CALL
);
533 g_dbus_message_set_serial (message
, 0x41);
534 s
= get_body_signature (value
);
535 g_dbus_message_set_header (message
, G_DBUS_MESSAGE_HEADER_FIELD_PATH
, g_variant_new_object_path ("/foo/bar"));
536 g_dbus_message_set_header (message
, G_DBUS_MESSAGE_HEADER_FIELD_MEMBER
, g_variant_new_string ("Member"));
537 g_dbus_message_set_header (message
, G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE
, g_variant_new_signature (s
));
540 /* First check that the serialization to the D-Bus wire format is correct - do this for both byte orders */
541 for (n
= 0; n
< 2; n
++)
543 GDBusMessageByteOrder byte_order
;
547 byte_order
= G_DBUS_MESSAGE_BYTE_ORDER_BIG_ENDIAN
;
550 byte_order
= G_DBUS_MESSAGE_BYTE_ORDER_LITTLE_ENDIAN
;
553 g_assert_not_reached ();
556 g_dbus_message_set_byte_order (message
, byte_order
);
559 blob
= g_dbus_message_to_blob (message
,
561 G_DBUS_CAPABILITY_FLAGS_NONE
,
563 g_assert_no_error (error
);
564 g_assert (blob
!= NULL
);
568 case G_DBUS_MESSAGE_BYTE_ORDER_BIG_ENDIAN
:
569 g_assert_cmpint (blob
[0], ==, 'B');
571 case G_DBUS_MESSAGE_BYTE_ORDER_LITTLE_ENDIAN
:
572 g_assert_cmpint (blob
[0], ==, 'l');
576 dbus_error_init (&dbus_error
);
577 dbus_1_message
= dbus_message_demarshal ((char *) blob
, blob_size
, &dbus_error
);
578 if (dbus_error_is_set (&dbus_error
))
580 g_printerr ("Error calling dbus_message_demarshal() on this blob: %s: %s\n",
583 hexdump (blob
, blob_size
);
584 dbus_error_free (&dbus_error
);
586 s
= g_variant_print (value
, TRUE
);
587 g_printerr ("\nThe blob was generated from the following GVariant value:\n%s\n\n", s
);
590 g_printerr ("If the blob was encoded using DBusMessageIter, the payload would have been:\n");
591 print_gv_dbus_message (value
);
593 g_assert_not_reached ();
596 s
= dbus_1_message_print (dbus_1_message
);
597 dbus_message_unref (dbus_1_message
);
599 g_assert_cmpstr (s
, ==, expected_dbus_1_output
);
602 /* Then serialize back and check that the body is identical */
605 recovered_message
= g_dbus_message_new_from_blob (blob
,
607 G_DBUS_CAPABILITY_FLAGS_NONE
,
609 g_assert_no_error (error
);
610 g_assert (recovered_message
!= NULL
);
614 g_assert (g_dbus_message_get_body (recovered_message
) == NULL
);
618 g_assert (g_dbus_message_get_body (recovered_message
) != NULL
);
619 if (!g_variant_equal (g_dbus_message_get_body (recovered_message
), value
))
621 s
= g_variant_print (g_dbus_message_get_body (recovered_message
), TRUE
);
622 s1
= g_variant_print (value
, TRUE
);
623 g_printerr ("Recovered value:\n%s\ndoes not match given value\n%s\n",
628 g_assert_not_reached ();
631 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_GUINT64_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");
697 g_variant_unref (value
);
699 value
= g_variant_parse (G_VARIANT_TYPE ("(sa{sv}as)"),
700 "('01234567890123456', {}, ['Something'])",
702 g_assert_no_error (error
);
703 g_assert (value
!= NULL
);
704 check_serialization (value
,
705 "value 0: string: '01234567890123456'\n"
708 " string: 'Something'\n");
709 g_variant_unref (value
);
711 /* https://bugzilla.gnome.org/show_bug.cgi?id=621838 */
712 check_serialization (g_variant_new_parsed ("(@aay [], {'cwd': <'/home/davidz/Hacking/glib/gio/tests'>})"),
718 " string: '/home/davidz/Hacking/glib/gio/tests'\n");
720 #ifdef DBUS_TYPE_UNIX_FD
721 value
= g_variant_parse (G_VARIANT_TYPE ("(hah)"),
724 g_assert_no_error (error
);
725 g_assert (value
!= NULL
);
726 /* about (not extracted), see comment in DBUS_TYPE_UNIX_FD case in
727 * dbus_1_message_append() above.
729 check_serialization (value
,
730 "value 0: unix-fd: (not extracted)\n"
732 " unix-fd: (not extracted)\n"
733 " unix-fd: (not extracted)\n");
734 g_variant_unref (value
);
739 /* ---------------------------------------------------------------------------------------------------- */
748 gsize slen
= strlen (before
) + 1;
750 g_assert_cmpuint (strlen (before
), ==, strlen (after
));
751 g_assert_cmpuint (len
, >=, slen
);
753 for (i
= 0; i
< (len
- slen
+ 1); i
++)
755 if (memcmp (blob
+ i
, before
, slen
) == 0)
756 memcpy (blob
+ i
, after
, slen
);
761 message_serialize_invalid (void)
765 /* Other things we could check (note that GDBus _does_ check for all
766 * these things - we just don't have test-suit coverage for it)
768 * - array exceeding 64 MiB (2^26 bytes) - unfortunately libdbus-1 checks
771 * process 19620: arguments to dbus_message_iter_append_fixed_array() were incorrect,
772 * assertion "n_elements <= DBUS_MAXIMUM_ARRAY_LENGTH / _dbus_type_get_alignment (element_type)"
773 * failed in file dbus-message.c line 2344.
774 * This is normally a bug in some application using the D-Bus library.
775 * D-Bus not built with -rdynamic so unable to print a backtrace
776 * Aborted (core dumped)
778 * - message exceeding 128 MiB (2^27 bytes)
780 * - endianness, message type, flags, protocol version
783 for (n
= 0; n
< 3; n
++)
785 GDBusMessage
*message
;
787 DBusMessage
*dbus_message
;
790 /* these are in pairs with matching length */
791 const gchar
*valid_utf8_str
= "this is valid...";
792 const gchar
*invalid_utf8_str
= "this is invalid\xff";
793 const gchar
*valid_signature
= "a{sv}a{sv}a{sv}aiai";
794 const gchar
*invalid_signature
= "not valid signature";
795 const gchar
*valid_object_path
= "/this/is/a/valid/dbus/object/path";
796 const gchar
*invalid_object_path
= "/this/is/not a valid object path!";
798 dbus_message
= dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_CALL
);
799 dbus_message_set_serial (dbus_message
, 0x41);
800 dbus_message_set_path (dbus_message
, "/foo/bar");
801 dbus_message_set_member (dbus_message
, "Member");
806 dbus_message_append_args (dbus_message
,
807 DBUS_TYPE_STRING
, &valid_utf8_str
,
812 /* invalid object path */
813 dbus_message_append_args (dbus_message
,
814 DBUS_TYPE_OBJECT_PATH
, &valid_object_path
,
819 /* invalid signature */
820 dbus_message_append_args (dbus_message
,
821 DBUS_TYPE_SIGNATURE
, &valid_signature
,
826 g_assert_not_reached ();
829 dbus_message_marshal (dbus_message
, &blob
, &blob_len
);
830 /* hack up the message to be invalid by replacing each valid string
831 * with its invalid counterpart */
832 replace (blob
, blob_len
, valid_utf8_str
, invalid_utf8_str
);
833 replace (blob
, blob_len
, valid_object_path
, invalid_object_path
);
834 replace (blob
, blob_len
, valid_signature
, invalid_signature
);
837 message
= g_dbus_message_new_from_blob ((guchar
*) blob
,
839 G_DBUS_CAPABILITY_FLAGS_NONE
,
841 g_assert_error (error
, G_IO_ERROR
, G_IO_ERROR_INVALID_ARGUMENT
);
842 g_error_free (error
);
843 g_assert (message
== NULL
);
846 dbus_message_unref (dbus_message
);
851 /* ---------------------------------------------------------------------------------------------------- */
854 message_serialize_header_checks (void)
856 GDBusMessage
*message
;
863 * check we can't serialize messages with INVALID type
865 message
= g_dbus_message_new ();
867 blob
= g_dbus_message_to_blob (message
, &blob_size
, G_DBUS_CAPABILITY_FLAGS_NONE
, &error
);
868 g_assert_error (error
, G_IO_ERROR
, G_IO_ERROR_INVALID_ARGUMENT
);
869 g_assert_cmpstr (error
->message
, ==, "Cannot serialize message: type is INVALID");
870 g_error_free (error
);
871 g_assert (blob
== NULL
);
872 g_object_unref (message
);
875 * check we can't serialize signal messages with INTERFACE, PATH or MEMBER unset / set to reserved value
877 message
= g_dbus_message_new_signal ("/the/path", "The.Interface", "TheMember");
879 /* interface NULL => error */
880 g_dbus_message_set_interface (message
, NULL
);
882 blob
= g_dbus_message_to_blob (message
, &blob_size
, G_DBUS_CAPABILITY_FLAGS_NONE
, &error
);
883 g_assert_error (error
, G_IO_ERROR
, G_IO_ERROR_INVALID_ARGUMENT
);
884 g_assert_cmpstr (error
->message
, ==, "Cannot serialize message: SIGNAL message: PATH, INTERFACE or MEMBER header field is missing");
885 g_error_free (error
);
886 g_assert (blob
== NULL
);
887 /* interface reserved value => error */
888 g_dbus_message_set_interface (message
, "org.freedesktop.DBus.Local");
890 blob
= g_dbus_message_to_blob (message
, &blob_size
, G_DBUS_CAPABILITY_FLAGS_NONE
, &error
);
891 g_assert_error (error
, G_IO_ERROR
, G_IO_ERROR_INVALID_ARGUMENT
);
892 g_assert_cmpstr (error
->message
, ==, "Cannot serialize message: SIGNAL message: The INTERFACE header field is using the reserved value org.freedesktop.DBus.Local");
893 g_error_free (error
);
894 g_assert (blob
== NULL
);
895 /* reset interface */
896 g_dbus_message_set_interface (message
, "The.Interface");
898 /* path NULL => error */
899 g_dbus_message_set_path (message
, NULL
);
901 blob
= g_dbus_message_to_blob (message
, &blob_size
, G_DBUS_CAPABILITY_FLAGS_NONE
, &error
);
902 g_assert_error (error
, G_IO_ERROR
, G_IO_ERROR_INVALID_ARGUMENT
);
903 g_assert_cmpstr (error
->message
, ==, "Cannot serialize message: SIGNAL message: PATH, INTERFACE or MEMBER header field is missing");
904 g_error_free (error
);
905 g_assert (blob
== NULL
);
906 /* path reserved value => error */
907 g_dbus_message_set_path (message
, "/org/freedesktop/DBus/Local");
909 blob
= g_dbus_message_to_blob (message
, &blob_size
, G_DBUS_CAPABILITY_FLAGS_NONE
, &error
);
910 g_assert_error (error
, G_IO_ERROR
, G_IO_ERROR_INVALID_ARGUMENT
);
911 g_assert_cmpstr (error
->message
, ==, "Cannot serialize message: SIGNAL message: The PATH header field is using the reserved value /org/freedesktop/DBus/Local");
912 g_error_free (error
);
913 g_assert (blob
== NULL
);
915 g_dbus_message_set_path (message
, "/the/path");
917 /* member NULL => error */
918 g_dbus_message_set_member (message
, NULL
);
920 blob
= g_dbus_message_to_blob (message
, &blob_size
, G_DBUS_CAPABILITY_FLAGS_NONE
, &error
);
921 g_assert_error (error
, G_IO_ERROR
, G_IO_ERROR_INVALID_ARGUMENT
);
922 g_assert_cmpstr (error
->message
, ==, "Cannot serialize message: SIGNAL message: PATH, INTERFACE or MEMBER header field is missing");
923 g_error_free (error
);
924 g_assert (blob
== NULL
);
926 g_dbus_message_set_member (message
, "TheMember");
929 g_object_unref (message
);
932 * check that we can't serialize method call messages with PATH or MEMBER unset
934 message
= g_dbus_message_new_method_call (NULL
, "/the/path", NULL
, "TheMember");
936 /* path NULL => error */
937 g_dbus_message_set_path (message
, NULL
);
939 blob
= g_dbus_message_to_blob (message
, &blob_size
, G_DBUS_CAPABILITY_FLAGS_NONE
, &error
);
940 g_assert_error (error
, G_IO_ERROR
, G_IO_ERROR_INVALID_ARGUMENT
);
941 g_assert_cmpstr (error
->message
, ==, "Cannot serialize message: METHOD_CALL message: PATH or MEMBER header field is missing");
942 g_error_free (error
);
943 g_assert (blob
== NULL
);
945 g_dbus_message_set_path (message
, "/the/path");
947 /* member NULL => error */
948 g_dbus_message_set_member (message
, NULL
);
950 blob
= g_dbus_message_to_blob (message
, &blob_size
, G_DBUS_CAPABILITY_FLAGS_NONE
, &error
);
951 g_assert_error (error
, G_IO_ERROR
, G_IO_ERROR_INVALID_ARGUMENT
);
952 g_assert_cmpstr (error
->message
, ==, "Cannot serialize message: METHOD_CALL message: PATH or MEMBER header field is missing");
953 g_error_free (error
);
954 g_assert (blob
== NULL
);
956 g_dbus_message_set_member (message
, "TheMember");
959 g_object_unref (message
);
962 * check that we can't serialize method reply messages with REPLY_SERIAL unset
964 message
= g_dbus_message_new_method_call (NULL
, "/the/path", NULL
, "TheMember");
965 g_dbus_message_set_serial (message
, 42);
967 reply
= g_dbus_message_new_method_reply (message
);
968 g_assert_cmpint (g_dbus_message_get_reply_serial (reply
), ==, 42);
969 g_dbus_message_set_header (reply
, G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL
, NULL
);
971 blob
= g_dbus_message_to_blob (reply
, &blob_size
, G_DBUS_CAPABILITY_FLAGS_NONE
, &error
);
972 g_assert_error (error
, G_IO_ERROR
, G_IO_ERROR_INVALID_ARGUMENT
);
973 g_assert_cmpstr (error
->message
, ==, "Cannot serialize message: METHOD_RETURN message: REPLY_SERIAL header field is missing");
974 g_error_free (error
);
975 g_assert (blob
== NULL
);
976 g_object_unref (reply
);
977 /* method error - first nuke ERROR_NAME, then REPLY_SERIAL */
978 reply
= g_dbus_message_new_method_error (message
, "Some.Error.Name", "the message");
979 g_assert_cmpint (g_dbus_message_get_reply_serial (reply
), ==, 42);
980 /* nuke ERROR_NAME */
981 g_dbus_message_set_error_name (reply
, NULL
);
983 blob
= g_dbus_message_to_blob (reply
, &blob_size
, G_DBUS_CAPABILITY_FLAGS_NONE
, &error
);
984 g_assert_error (error
, G_IO_ERROR
, G_IO_ERROR_INVALID_ARGUMENT
);
985 g_assert_cmpstr (error
->message
, ==, "Cannot serialize message: ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing");
986 g_error_free (error
);
987 g_assert (blob
== NULL
);
988 /* reset ERROR_NAME */
989 g_dbus_message_set_error_name (reply
, "Some.Error.Name");
990 /* nuke REPLY_SERIAL */
991 g_dbus_message_set_header (reply
, G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL
, NULL
);
993 blob
= g_dbus_message_to_blob (reply
, &blob_size
, G_DBUS_CAPABILITY_FLAGS_NONE
, &error
);
994 g_assert_error (error
, G_IO_ERROR
, G_IO_ERROR_INVALID_ARGUMENT
);
995 g_assert_cmpstr (error
->message
, ==, "Cannot serialize message: ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing");
996 g_error_free (error
);
997 g_assert (blob
== NULL
);
998 g_object_unref (reply
);
999 g_object_unref (message
);
1002 /* ---------------------------------------------------------------------------------------------------- */
1005 message_parse_empty_arrays_of_arrays (void)
1008 GError
*error
= NULL
;
1010 g_test_bug ("673612");
1011 /* These three-element array of empty arrays were previously read back as a
1012 * two-element array of empty arrays, due to sometimes erroneously skipping
1013 * four bytes to align for the eight-byte-aligned grandchild types (x and
1016 body
= g_variant_parse (G_VARIANT_TYPE ("(aaax)"),
1017 "([@aax [], [], []],)", NULL
, NULL
, &error
);
1018 g_assert_no_error (error
);
1019 check_serialization (body
,
1024 g_variant_unref (body
);
1026 body
= g_variant_parse (G_VARIANT_TYPE ("(aaa{uu})"),
1027 "([@aa{uu} [], [], []],)", NULL
, NULL
, &error
);
1028 g_assert_no_error (error
);
1029 check_serialization (body
,
1034 g_variant_unref (body
);
1036 /* Due to the same bug, g_dbus_message_new_from_blob() would fail for this
1037 * message because it would try to read past the end of the string. Hence,
1038 * sending this to an application would make it fall off the bus. */
1039 body
= g_variant_parse (G_VARIANT_TYPE ("(a(aa{sv}as))"),
1042 " ([], [])],)", NULL
, NULL
, &error
);
1043 g_assert_no_error (error
);
1044 check_serialization (body
,
1055 g_variant_unref (body
);
1058 /* ---------------------------------------------------------------------------------------------------- */
1061 test_double_array (void)
1063 GVariantBuilder builder
;
1066 g_test_bug ("732754");
1068 g_variant_builder_init (&builder
, G_VARIANT_TYPE ("ad"));
1069 g_variant_builder_add (&builder
, "d", (gdouble
)0.0);
1070 g_variant_builder_add (&builder
, "d", (gdouble
)8.0);
1071 g_variant_builder_add (&builder
, "d", (gdouble
)22.0);
1072 g_variant_builder_add (&builder
, "d", (gdouble
)0.0);
1073 body
= g_variant_new ("(@ad)", g_variant_builder_end (&builder
));
1074 check_serialization (body
,
1076 " double: 0.000000\n"
1077 " double: 8.000000\n"
1078 " double: 22.000000\n"
1079 " double: 0.000000\n");
1082 /* ---------------------------------------------------------------------------------------------------- */
1088 g_setenv ("LC_ALL", "C", TRUE
);
1089 setlocale (LC_ALL
, "C");
1091 g_test_init (&argc
, &argv
, NULL
);
1092 g_test_bug_base ("https://bugzilla.gnome.org/show_bug.cgi?id=");
1094 g_test_add_func ("/gdbus/message-serialize-basic", message_serialize_basic
);
1095 g_test_add_func ("/gdbus/message-serialize-complex", message_serialize_complex
);
1096 g_test_add_func ("/gdbus/message-serialize-invalid", message_serialize_invalid
);
1097 g_test_add_func ("/gdbus/message-serialize-header-checks", message_serialize_header_checks
);
1099 g_test_add_func ("/gdbus/message-parse-empty-arrays-of-arrays",
1100 message_parse_empty_arrays_of_arrays
);
1102 g_test_add_func ("/gdbus/message-serialize/double-array", test_double_array
);
1104 return g_test_run();