Branch data Line data Source code
1 : : /* GLib testing framework examples and tests
2 : : *
3 : : * Copyright (C) 2008-2010 Red Hat, Inc.
4 : : *
5 : : * SPDX-License-Identifier: LGPL-2.1-or-later
6 : : *
7 : : * This library is free software; you can redistribute it and/or
8 : : * modify it under the terms of the GNU Lesser General Public
9 : : * License as published by the Free Software Foundation; either
10 : : * version 2.1 of the License, or (at your option) any later version.
11 : : *
12 : : * This library is distributed in the hope that it will be useful,
13 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 : : * Lesser General Public License for more details.
16 : : *
17 : : * You should have received a copy of the GNU Lesser General
18 : : * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
19 : : *
20 : : * Author: David Zeuthen <davidz@redhat.com>
21 : : */
22 : :
23 : : #include <locale.h>
24 : : #include <gio/gio.h>
25 : :
26 : : #include <string.h>
27 : : #ifndef _MSC_VER
28 : : #include <unistd.h>
29 : : #endif
30 : : #include <dbus/dbus.h>
31 : :
32 : : /* ---------------------------------------------------------------------------------------------------- */
33 : :
34 : : static void
35 : 0 : hexdump (const guchar *str, gsize len)
36 : : {
37 : 0 : const guchar *data = (const guchar *) str;
38 : : guint n, m;
39 : :
40 : 0 : for (n = 0; n < len; n += 16)
41 : : {
42 : 0 : g_printerr ("%04x: ", n);
43 : :
44 : 0 : for (m = n; m < n + 16; m++)
45 : : {
46 : 0 : if (m > n && (m%4) == 0)
47 : 0 : g_printerr (" ");
48 : 0 : if (m < len)
49 : 0 : g_printerr ("%02x ", data[m]);
50 : : else
51 : 0 : g_printerr (" ");
52 : : }
53 : :
54 : 0 : g_printerr (" ");
55 : :
56 : 0 : for (m = n; m < len && m < n + 16; m++)
57 : 0 : g_printerr ("%c", g_ascii_isprint (data[m]) ? data[m] : '.');
58 : :
59 : 0 : g_printerr ("\n");
60 : : }
61 : 0 : }
62 : :
63 : : /* ---------------------------------------------------------------------------------------------------- */
64 : :
65 : : static gboolean
66 : 0 : append_gv_to_dbus_iter (DBusMessageIter *iter,
67 : : GVariant *value,
68 : : GError **error)
69 : : {
70 : : const GVariantType *type;
71 : :
72 : 0 : type = g_variant_get_type (value);
73 : 0 : if (g_variant_type_equal (type, G_VARIANT_TYPE_BOOLEAN))
74 : : {
75 : 0 : dbus_bool_t v = g_variant_get_boolean (value);
76 : 0 : dbus_message_iter_append_basic (iter, DBUS_TYPE_BOOLEAN, &v);
77 : : }
78 : 0 : else if (g_variant_type_equal (type, G_VARIANT_TYPE_BYTE))
79 : : {
80 : 0 : guint8 v = g_variant_get_byte (value);
81 : 0 : dbus_message_iter_append_basic (iter, DBUS_TYPE_BYTE, &v);
82 : : }
83 : 0 : else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT16))
84 : : {
85 : 0 : gint16 v = g_variant_get_int16 (value);
86 : 0 : dbus_message_iter_append_basic (iter, DBUS_TYPE_INT16, &v);
87 : : }
88 : 0 : else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT16))
89 : : {
90 : 0 : guint16 v = g_variant_get_uint16 (value);
91 : 0 : dbus_message_iter_append_basic (iter, DBUS_TYPE_UINT16, &v);
92 : : }
93 : 0 : else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32))
94 : : {
95 : 0 : gint32 v = g_variant_get_int32 (value);
96 : 0 : dbus_message_iter_append_basic (iter, DBUS_TYPE_INT32, &v);
97 : : }
98 : 0 : else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT32))
99 : : {
100 : 0 : guint32 v = g_variant_get_uint32 (value);
101 : 0 : dbus_message_iter_append_basic (iter, DBUS_TYPE_UINT32, &v);
102 : : }
103 : 0 : else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT64))
104 : : {
105 : 0 : gint64 v = g_variant_get_int64 (value);
106 : 0 : dbus_message_iter_append_basic (iter, DBUS_TYPE_INT64, &v);
107 : : }
108 : 0 : else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT64))
109 : : {
110 : 0 : guint64 v = g_variant_get_uint64 (value);
111 : 0 : dbus_message_iter_append_basic (iter, DBUS_TYPE_UINT64, &v);
112 : : }
113 : 0 : else if (g_variant_type_equal (type, G_VARIANT_TYPE_DOUBLE))
114 : : {
115 : 0 : gdouble v = g_variant_get_double (value);
116 : 0 : dbus_message_iter_append_basic (iter, DBUS_TYPE_DOUBLE, &v);
117 : : }
118 : 0 : else if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING))
119 : : {
120 : 0 : const gchar *v = g_variant_get_string (value, NULL);
121 : 0 : dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &v);
122 : : }
123 : 0 : else if (g_variant_type_equal (type, G_VARIANT_TYPE_OBJECT_PATH))
124 : : {
125 : 0 : const gchar *v = g_variant_get_string (value, NULL);
126 : 0 : dbus_message_iter_append_basic (iter, DBUS_TYPE_OBJECT_PATH, &v);
127 : : }
128 : 0 : else if (g_variant_type_equal (type, G_VARIANT_TYPE_SIGNATURE))
129 : : {
130 : 0 : const gchar *v = g_variant_get_string (value, NULL);
131 : 0 : dbus_message_iter_append_basic (iter, DBUS_TYPE_SIGNATURE, &v);
132 : : }
133 : 0 : else if (g_variant_type_is_variant (type))
134 : : {
135 : : DBusMessageIter sub;
136 : : GVariant *child;
137 : :
138 : 0 : child = g_variant_get_child_value (value, 0);
139 : 0 : dbus_message_iter_open_container (iter, DBUS_TYPE_VARIANT,
140 : 0 : g_variant_get_type_string (child),
141 : : &sub);
142 : 0 : if (!append_gv_to_dbus_iter (&sub, child, error))
143 : : {
144 : 0 : g_variant_unref (child);
145 : 0 : goto fail;
146 : : }
147 : 0 : dbus_message_iter_close_container (iter, &sub);
148 : 0 : g_variant_unref (child);
149 : : }
150 : 0 : else if (g_variant_type_is_array (type))
151 : : {
152 : : DBusMessageIter dbus_iter;
153 : : const gchar *type_string;
154 : : GVariantIter gv_iter;
155 : : GVariant *item;
156 : :
157 : 0 : type_string = g_variant_get_type_string (value);
158 : 0 : type_string++; /* skip the 'a' */
159 : :
160 : 0 : dbus_message_iter_open_container (iter, DBUS_TYPE_ARRAY,
161 : : type_string, &dbus_iter);
162 : 0 : g_variant_iter_init (&gv_iter, value);
163 : :
164 : 0 : while ((item = g_variant_iter_next_value (&gv_iter)))
165 : : {
166 : 0 : if (!append_gv_to_dbus_iter (&dbus_iter, item, error))
167 : : {
168 : 0 : goto fail;
169 : : }
170 : : }
171 : :
172 : 0 : dbus_message_iter_close_container (iter, &dbus_iter);
173 : : }
174 : 0 : else if (g_variant_type_is_tuple (type))
175 : : {
176 : : DBusMessageIter dbus_iter;
177 : : GVariantIter gv_iter;
178 : : GVariant *item;
179 : :
180 : 0 : dbus_message_iter_open_container (iter, DBUS_TYPE_STRUCT,
181 : : NULL, &dbus_iter);
182 : 0 : g_variant_iter_init (&gv_iter, value);
183 : :
184 : 0 : while ((item = g_variant_iter_next_value (&gv_iter)))
185 : : {
186 : 0 : if (!append_gv_to_dbus_iter (&dbus_iter, item, error))
187 : 0 : goto fail;
188 : : }
189 : :
190 : 0 : dbus_message_iter_close_container (iter, &dbus_iter);
191 : : }
192 : 0 : else if (g_variant_type_is_dict_entry (type))
193 : : {
194 : : DBusMessageIter dbus_iter;
195 : : GVariant *key, *val;
196 : :
197 : 0 : dbus_message_iter_open_container (iter, DBUS_TYPE_DICT_ENTRY,
198 : : NULL, &dbus_iter);
199 : 0 : key = g_variant_get_child_value (value, 0);
200 : 0 : if (!append_gv_to_dbus_iter (&dbus_iter, key, error))
201 : : {
202 : 0 : g_variant_unref (key);
203 : 0 : goto fail;
204 : : }
205 : 0 : g_variant_unref (key);
206 : :
207 : 0 : val = g_variant_get_child_value (value, 1);
208 : 0 : if (!append_gv_to_dbus_iter (&dbus_iter, val, error))
209 : : {
210 : 0 : g_variant_unref (val);
211 : 0 : goto fail;
212 : : }
213 : 0 : g_variant_unref (val);
214 : :
215 : 0 : dbus_message_iter_close_container (iter, &dbus_iter);
216 : : }
217 : : else
218 : : {
219 : 0 : g_set_error (error,
220 : : G_IO_ERROR,
221 : : G_IO_ERROR_INVALID_ARGUMENT,
222 : : "Error serializing GVariant with type-string '%s' to a D-Bus message",
223 : : g_variant_get_type_string (value));
224 : 0 : goto fail;
225 : : }
226 : :
227 : 0 : return TRUE;
228 : :
229 : 0 : fail:
230 : 0 : return FALSE;
231 : : }
232 : :
233 : : static gboolean
234 : 0 : append_gv_to_dbus_message (DBusMessage *message,
235 : : GVariant *value,
236 : : GError **error)
237 : : {
238 : : gboolean ret;
239 : : guint n;
240 : :
241 : 0 : ret = FALSE;
242 : :
243 : 0 : if (value != NULL)
244 : : {
245 : : DBusMessageIter iter;
246 : : GVariantIter gv_iter;
247 : : GVariant *item;
248 : :
249 : 0 : dbus_message_iter_init_append (message, &iter);
250 : :
251 : 0 : g_variant_iter_init (&gv_iter, value);
252 : 0 : n = 0;
253 : 0 : while ((item = g_variant_iter_next_value (&gv_iter)))
254 : : {
255 : 0 : if (!append_gv_to_dbus_iter (&iter, item, error))
256 : : {
257 : 0 : g_prefix_error (error,
258 : : "Error encoding in-arg %d: ",
259 : : n);
260 : 0 : goto out;
261 : : }
262 : 0 : n++;
263 : : }
264 : : }
265 : :
266 : 0 : ret = TRUE;
267 : :
268 : 0 : out:
269 : 0 : return ret;
270 : : }
271 : :
272 : : static void
273 : 0 : print_gv_dbus_message (GVariant *value)
274 : : {
275 : : DBusMessage *message;
276 : : char *blob;
277 : : int blob_len;
278 : : GError *error;
279 : :
280 : 0 : message = dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_CALL);
281 : 0 : dbus_message_set_serial (message, 0x41);
282 : 0 : dbus_message_set_path (message, "/foo/bar");
283 : 0 : dbus_message_set_member (message, "Member");
284 : :
285 : 0 : error = NULL;
286 : 0 : if (!append_gv_to_dbus_message (message, value, &error))
287 : : {
288 : 0 : g_printerr ("Error printing GVariant as DBusMessage: %s", error->message);
289 : 0 : g_error_free (error);
290 : 0 : goto out;
291 : : }
292 : :
293 : 0 : dbus_message_marshal (message, &blob, &blob_len);
294 : 0 : g_printerr ("\n");
295 : 0 : hexdump ((guchar *) blob, blob_len);
296 : 0 : out:
297 : 0 : dbus_message_unref (message);
298 : 0 : }
299 : :
300 : : /* ---------------------------------------------------------------------------------------------------- */
301 : :
302 : : static void
303 : 380 : dbus_1_message_append (GString *s,
304 : : guint indent,
305 : : DBusMessageIter *iter)
306 : : {
307 : : gint arg_type;
308 : : DBusMessageIter sub;
309 : :
310 : 380 : g_string_append_printf (s, "%*s", indent, "");
311 : :
312 : 380 : arg_type = dbus_message_iter_get_arg_type (iter);
313 : 380 : switch (arg_type)
314 : : {
315 : 2 : case DBUS_TYPE_BOOLEAN:
316 : : {
317 : : dbus_bool_t value;
318 : 2 : dbus_message_iter_get_basic (iter, &value);
319 : 2 : g_string_append_printf (s, "bool: %s\n", value ? "true" : "false");
320 : 2 : break;
321 : : }
322 : :
323 : 2 : case DBUS_TYPE_BYTE:
324 : : {
325 : : guchar value;
326 : 2 : dbus_message_iter_get_basic (iter, &value);
327 : 2 : g_string_append_printf (s, "byte: 0x%02x\n", (guint) value);
328 : 2 : break;
329 : : }
330 : :
331 : 2 : case DBUS_TYPE_INT16:
332 : : {
333 : : gint16 value;
334 : 2 : dbus_message_iter_get_basic (iter, &value);
335 : 2 : g_string_append_printf (s, "int16: %" G_GINT16_FORMAT "\n", value);
336 : 2 : break;
337 : : }
338 : :
339 : 2 : case DBUS_TYPE_UINT16:
340 : : {
341 : : guint16 value;
342 : 2 : dbus_message_iter_get_basic (iter, &value);
343 : 2 : g_string_append_printf (s, "uint16: %" G_GUINT16_FORMAT "\n", value);
344 : 2 : break;
345 : : }
346 : :
347 : 8 : case DBUS_TYPE_INT32:
348 : : {
349 : : gint32 value;
350 : 8 : dbus_message_iter_get_basic (iter, &value);
351 : 8 : g_string_append_printf (s, "int32: %" G_GINT32_FORMAT "\n", value);
352 : 8 : break;
353 : : }
354 : :
355 : 2 : case DBUS_TYPE_UINT32:
356 : : {
357 : : guint32 value;
358 : 2 : dbus_message_iter_get_basic (iter, &value);
359 : 2 : g_string_append_printf (s, "uint32: %" G_GUINT32_FORMAT "\n", value);
360 : 2 : break;
361 : : }
362 : :
363 : 2 : case DBUS_TYPE_INT64:
364 : : {
365 : : gint64 value;
366 : 2 : dbus_message_iter_get_basic (iter, &value);
367 : 2 : g_string_append_printf (s, "int64: %" G_GINT64_FORMAT "\n", value);
368 : 2 : break;
369 : : }
370 : :
371 : 2 : case DBUS_TYPE_UINT64:
372 : : {
373 : : guint64 value;
374 : 2 : dbus_message_iter_get_basic (iter, &value);
375 : 2 : g_string_append_printf (s, "uint64: %" G_GUINT64_FORMAT "\n", value);
376 : 2 : break;
377 : : }
378 : :
379 : 10 : case DBUS_TYPE_DOUBLE:
380 : : {
381 : : gdouble value;
382 : 10 : dbus_message_iter_get_basic (iter, &value);
383 : 10 : g_string_append_printf (s, "double: %f\n", value);
384 : 10 : break;
385 : : }
386 : :
387 : 22 : case DBUS_TYPE_STRING:
388 : : {
389 : : const gchar *value;
390 : 22 : dbus_message_iter_get_basic (iter, &value);
391 : 22 : g_string_append_printf (s, "string: '%s'\n", value);
392 : 22 : break;
393 : : }
394 : :
395 : 2 : case DBUS_TYPE_OBJECT_PATH:
396 : : {
397 : : const gchar *value;
398 : 2 : dbus_message_iter_get_basic (iter, &value);
399 : 2 : g_string_append_printf (s, "object_path: '%s'\n", value);
400 : 2 : break;
401 : : }
402 : :
403 : 2 : case DBUS_TYPE_SIGNATURE:
404 : : {
405 : : const gchar *value;
406 : 2 : dbus_message_iter_get_basic (iter, &value);
407 : 2 : g_string_append_printf (s, "signature: '%s'\n", value);
408 : 2 : break;
409 : : }
410 : :
411 : : #ifdef DBUS_TYPE_UNIX_FD
412 : 6 : case DBUS_TYPE_UNIX_FD:
413 : : {
414 : : /* unfortunately there's currently no way to get just the
415 : : * protocol value, since dbus_message_iter_get_basic() wants
416 : : * to be 'helpful' and dup the fd for the user...
417 : : */
418 : 6 : g_string_append (s, "unix-fd: (not extracted)\n");
419 : 6 : break;
420 : : }
421 : : #endif
422 : :
423 : 130 : case DBUS_TYPE_VARIANT:
424 : 130 : g_string_append_printf (s, "variant:\n");
425 : 130 : dbus_message_iter_recurse (iter, &sub);
426 : 260 : while (dbus_message_iter_get_arg_type (&sub))
427 : : {
428 : 130 : dbus_1_message_append (s, indent + 2, &sub);
429 : 130 : dbus_message_iter_next (&sub);
430 : : }
431 : 130 : break;
432 : :
433 : 110 : case DBUS_TYPE_ARRAY:
434 : 110 : g_string_append_printf (s, "array:\n");
435 : 110 : dbus_message_iter_recurse (iter, &sub);
436 : 218 : while (dbus_message_iter_get_arg_type (&sub))
437 : : {
438 : 108 : dbus_1_message_append (s, indent + 2, &sub);
439 : 108 : dbus_message_iter_next (&sub);
440 : : }
441 : 110 : break;
442 : :
443 : 70 : case DBUS_TYPE_STRUCT:
444 : 70 : g_string_append_printf (s, "struct:\n");
445 : 70 : dbus_message_iter_recurse (iter, &sub);
446 : 146 : while (dbus_message_iter_get_arg_type (&sub))
447 : : {
448 : 76 : dbus_1_message_append (s, indent + 2, &sub);
449 : 76 : dbus_message_iter_next (&sub);
450 : : }
451 : 70 : break;
452 : :
453 : 6 : case DBUS_TYPE_DICT_ENTRY:
454 : 6 : g_string_append_printf (s, "dict_entry:\n");
455 : 6 : dbus_message_iter_recurse (iter, &sub);
456 : 18 : while (dbus_message_iter_get_arg_type (&sub))
457 : : {
458 : 12 : dbus_1_message_append (s, indent + 2, &sub);
459 : 12 : dbus_message_iter_next (&sub);
460 : : }
461 : 6 : break;
462 : :
463 : 0 : default:
464 : 0 : g_printerr ("Error serializing D-Bus message to GVariant. Unsupported arg type '%c' (%d)",
465 : : arg_type,
466 : : arg_type);
467 : : g_assert_not_reached ();
468 : : break;
469 : : }
470 : 380 : }
471 : :
472 : : static gchar *
473 : 24 : dbus_1_message_print (DBusMessage *message)
474 : : {
475 : : GString *s;
476 : : guint n;
477 : : DBusMessageIter iter;
478 : :
479 : 24 : s = g_string_new (NULL);
480 : 24 : n = 0;
481 : 24 : dbus_message_iter_init (message, &iter);
482 : 78 : while (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_INVALID)
483 : : {
484 : 54 : g_string_append_printf (s, "value %d: ", n);
485 : 54 : dbus_1_message_append (s, 2, &iter);
486 : 54 : dbus_message_iter_next (&iter);
487 : 54 : n++;
488 : : }
489 : :
490 : 24 : return g_string_free (s, FALSE);
491 : : }
492 : :
493 : : /* ---------------------------------------------------------------------------------------------------- */
494 : :
495 : : static gchar *
496 : 12 : get_body_signature (GVariant *value)
497 : : {
498 : : const gchar *s;
499 : : gsize len;
500 : : gchar *ret;
501 : :
502 : 12 : if (value == NULL)
503 : : {
504 : 1 : ret = g_strdup ("");
505 : 1 : goto out;
506 : : }
507 : :
508 : 11 : s = g_variant_get_type_string (value);
509 : 11 : len = strlen (s);
510 : 11 : g_assert (len >= 2);
511 : :
512 : 11 : ret = g_strndup (s + 1, len - 2);
513 : :
514 : 12 : out:
515 : 12 : return ret;
516 : : }
517 : :
518 : : /* If @value is floating, this assumes ownership. */
519 : : static gchar *
520 : 12 : get_and_check_serialization (GVariant *value)
521 : : {
522 : : guchar *blob;
523 : : gsize blob_size;
524 : : DBusMessage *dbus_1_message;
525 : : GDBusMessage *message;
526 : : GDBusMessage *recovered_message;
527 : : GError *error;
528 : : DBusError dbus_error;
529 : 12 : gchar *last_serialization = NULL;
530 : 12 : gchar *s = NULL;
531 : : guint n;
532 : :
533 : 12 : message = g_dbus_message_new ();
534 : 12 : g_dbus_message_set_body (message, value);
535 : 12 : g_dbus_message_set_message_type (message, G_DBUS_MESSAGE_TYPE_METHOD_CALL);
536 : 12 : g_dbus_message_set_serial (message, 0x41);
537 : 12 : s = get_body_signature (value);
538 : 12 : g_dbus_message_set_header (message, G_DBUS_MESSAGE_HEADER_FIELD_PATH, g_variant_new_object_path ("/foo/bar"));
539 : 12 : g_dbus_message_set_header (message, G_DBUS_MESSAGE_HEADER_FIELD_MEMBER, g_variant_new_string ("Member"));
540 : 12 : g_dbus_message_set_header (message, G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE, g_variant_new_signature (s));
541 : 12 : g_free (s);
542 : :
543 : : /* First check that the serialization to the D-Bus wire format is correct - do this for both byte orders */
544 : 36 : for (n = 0; n < 2; n++)
545 : : {
546 : 24 : GDBusMessageByteOrder byte_order = G_DBUS_MESSAGE_BYTE_ORDER_BIG_ENDIAN;
547 : 24 : switch (n)
548 : : {
549 : 12 : case 0:
550 : 12 : byte_order = G_DBUS_MESSAGE_BYTE_ORDER_BIG_ENDIAN;
551 : 12 : break;
552 : 12 : case 1:
553 : 12 : byte_order = G_DBUS_MESSAGE_BYTE_ORDER_LITTLE_ENDIAN;
554 : 12 : break;
555 : 0 : case 2:
556 : : g_assert_not_reached ();
557 : : break;
558 : : }
559 : 24 : g_dbus_message_set_byte_order (message, byte_order);
560 : :
561 : 24 : error = NULL;
562 : 24 : blob = g_dbus_message_to_blob (message,
563 : : &blob_size,
564 : : G_DBUS_CAPABILITY_FLAGS_NONE,
565 : : &error);
566 : 24 : g_assert_no_error (error);
567 : 24 : g_assert (blob != NULL);
568 : :
569 : 24 : switch (byte_order)
570 : : {
571 : 12 : case G_DBUS_MESSAGE_BYTE_ORDER_BIG_ENDIAN:
572 : 12 : g_assert_cmpint (blob[0], ==, 'B');
573 : 12 : break;
574 : 12 : case G_DBUS_MESSAGE_BYTE_ORDER_LITTLE_ENDIAN:
575 : 12 : g_assert_cmpint (blob[0], ==, 'l');
576 : 12 : break;
577 : : }
578 : :
579 : 24 : dbus_error_init (&dbus_error);
580 : 24 : dbus_1_message = dbus_message_demarshal ((char *) blob, blob_size, &dbus_error);
581 : 24 : if (dbus_error_is_set (&dbus_error))
582 : : {
583 : 0 : g_printerr ("Error calling dbus_message_demarshal() on this blob: %s: %s\n",
584 : : dbus_error.name,
585 : : dbus_error.message);
586 : 0 : hexdump (blob, blob_size);
587 : 0 : dbus_error_free (&dbus_error);
588 : :
589 : 0 : s = g_variant_print (value, TRUE);
590 : 0 : g_printerr ("\nThe blob was generated from the following GVariant value:\n%s\n\n", s);
591 : 0 : g_free (s);
592 : :
593 : 0 : g_printerr ("If the blob was encoded using DBusMessageIter, the payload would have been:\n");
594 : 0 : print_gv_dbus_message (value);
595 : :
596 : : g_assert_not_reached ();
597 : : }
598 : :
599 : 24 : s = dbus_1_message_print (dbus_1_message);
600 : 24 : dbus_message_unref (dbus_1_message);
601 : :
602 : : /* Then serialize back and check that the body is identical */
603 : :
604 : 24 : error = NULL;
605 : 24 : recovered_message = g_dbus_message_new_from_blob (blob,
606 : : blob_size,
607 : : G_DBUS_CAPABILITY_FLAGS_NONE,
608 : : &error);
609 : 24 : g_assert_no_error (error);
610 : 24 : g_assert (recovered_message != NULL);
611 : :
612 : 24 : if (value == NULL)
613 : : {
614 : 2 : g_assert (g_dbus_message_get_body (recovered_message) == NULL);
615 : : }
616 : : else
617 : : {
618 : 22 : g_assert (g_dbus_message_get_body (recovered_message) != NULL);
619 : 22 : g_assert_cmpvariant (g_dbus_message_get_body (recovered_message), value);
620 : : }
621 : 24 : g_object_unref (recovered_message);
622 : 24 : g_free (blob);
623 : :
624 : 24 : if (last_serialization != NULL)
625 : : {
626 : 12 : g_assert_cmpstr (last_serialization, ==, s);
627 : 12 : g_free (last_serialization);
628 : : }
629 : :
630 : 24 : last_serialization = g_steal_pointer (&s);
631 : : }
632 : :
633 : 12 : g_object_unref (message);
634 : :
635 : 12 : return g_steal_pointer (&last_serialization);
636 : : }
637 : :
638 : : /* If @value is floating, this assumes ownership. */
639 : : static void
640 : 10 : check_serialization (GVariant *value,
641 : : const gchar *expected_dbus_1_output)
642 : : {
643 : 10 : gchar *s = get_and_check_serialization (value);
644 : 10 : g_assert_cmpstr (s, ==, expected_dbus_1_output);
645 : 10 : g_free (s);
646 : 10 : }
647 : :
648 : : static void
649 : 1 : test_message_serialize_basic (void)
650 : : {
651 : 1 : check_serialization (NULL, "");
652 : :
653 : 1 : check_serialization (g_variant_new ("(sogybnqiuxtd)",
654 : : "this is a string",
655 : : "/this/is/a/path",
656 : : "sad",
657 : : 42,
658 : : TRUE,
659 : : -42,
660 : : 60000,
661 : : -44,
662 : : 100000,
663 : : -(G_GUINT64_CONSTANT(2)<<34),
664 : : G_GUINT64_CONSTANT(0xffffffffffffffff),
665 : : 42.5),
666 : : "value 0: string: 'this is a string'\n"
667 : : "value 1: object_path: '/this/is/a/path'\n"
668 : : "value 2: signature: 'sad'\n"
669 : : "value 3: byte: 0x2a\n"
670 : : "value 4: bool: true\n"
671 : : "value 5: int16: -42\n"
672 : : "value 6: uint16: 60000\n"
673 : : "value 7: int32: -44\n"
674 : : "value 8: uint32: 100000\n"
675 : : "value 9: int64: -34359738368\n"
676 : : "value 10: uint64: 18446744073709551615\n"
677 : : "value 11: double: 42.500000\n");
678 : 1 : }
679 : :
680 : : /* ---------------------------------------------------------------------------------------------------- */
681 : :
682 : : static void
683 : 1 : test_message_serialize_complex (void)
684 : : {
685 : : GError *error;
686 : : GVariant *value;
687 : : guint i;
688 : 1 : gchar *serialization = NULL;
689 : :
690 : 1 : error = NULL;
691 : :
692 : 1 : value = g_variant_parse (G_VARIANT_TYPE ("(aia{ss})"),
693 : : "([1, 2, 3], {'one': 'white', 'two': 'black'})",
694 : : NULL, NULL, &error);
695 : 1 : g_assert_no_error (error);
696 : 1 : g_assert (value != NULL);
697 : 1 : check_serialization (value,
698 : : "value 0: array:\n"
699 : : " int32: 1\n"
700 : : " int32: 2\n"
701 : : " int32: 3\n"
702 : : "value 1: array:\n"
703 : : " dict_entry:\n"
704 : : " string: 'one'\n"
705 : : " string: 'white'\n"
706 : : " dict_entry:\n"
707 : : " string: 'two'\n"
708 : : " string: 'black'\n");
709 : 1 : g_variant_unref (value);
710 : :
711 : 1 : value = g_variant_parse (G_VARIANT_TYPE ("(sa{sv}as)"),
712 : : "('01234567890123456', {}, ['Something'])",
713 : : NULL, NULL, &error);
714 : 1 : g_assert_no_error (error);
715 : 1 : g_assert (value != NULL);
716 : 1 : check_serialization (value,
717 : : "value 0: string: '01234567890123456'\n"
718 : : "value 1: array:\n"
719 : : "value 2: array:\n"
720 : : " string: 'Something'\n");
721 : 1 : g_variant_unref (value);
722 : :
723 : : /* https://bugzilla.gnome.org/show_bug.cgi?id=621838 */
724 : 1 : check_serialization (g_variant_new_parsed ("(@aay [], {'cwd': <'/home/davidz/Hacking/glib/gio/tests'>})"),
725 : : "value 0: array:\n"
726 : : "value 1: array:\n"
727 : : " dict_entry:\n"
728 : : " string: 'cwd'\n"
729 : : " variant:\n"
730 : : " string: '/home/davidz/Hacking/glib/gio/tests'\n");
731 : :
732 : : #ifdef DBUS_TYPE_UNIX_FD
733 : 1 : value = g_variant_parse (G_VARIANT_TYPE ("(hah)"),
734 : : "(42, [43, 44])",
735 : : NULL, NULL, &error);
736 : 1 : g_assert_no_error (error);
737 : 1 : g_assert (value != NULL);
738 : : /* about (not extracted), see comment in DBUS_TYPE_UNIX_FD case in
739 : : * dbus_1_message_append() above.
740 : : */
741 : 1 : check_serialization (value,
742 : : "value 0: unix-fd: (not extracted)\n"
743 : : "value 1: array:\n"
744 : : " unix-fd: (not extracted)\n"
745 : : " unix-fd: (not extracted)\n");
746 : 1 : g_variant_unref (value);
747 : : #endif
748 : :
749 : : /* Deep nesting of variants (just below the recursion limit). */
750 : 1 : value = g_variant_new_string ("buried");
751 : 65 : for (i = 0; i < 64; i++)
752 : 64 : value = g_variant_new_variant (value);
753 : 1 : value = g_variant_new_tuple (&value, 1);
754 : :
755 : 1 : serialization = get_and_check_serialization (value);
756 : 1 : g_assert_nonnull (serialization);
757 : 1 : g_assert_true (g_str_has_prefix (serialization,
758 : : "value 0: variant:\n"
759 : : " variant:\n"
760 : : " variant:\n"));
761 : 1 : g_free (serialization);
762 : :
763 : : /* Deep nesting of arrays and structs (just below the recursion limit).
764 : : * See https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-marshaling-signature */
765 : 1 : value = g_variant_new_string ("hello");
766 : 33 : for (i = 0; i < 32; i++)
767 : 32 : value = g_variant_new_tuple (&value, 1);
768 : 33 : for (i = 0; i < 32; i++)
769 : 32 : value = g_variant_new_array (NULL, &value, 1);
770 : 1 : value = g_variant_new_tuple (&value, 1);
771 : :
772 : 1 : serialization = get_and_check_serialization (value);
773 : 1 : g_assert_nonnull (serialization);
774 : 1 : g_assert_true (g_str_has_prefix (serialization,
775 : : "value 0: array:\n"
776 : : " array:\n"
777 : : " array:\n"));
778 : 1 : g_free (serialization);
779 : 1 : }
780 : :
781 : :
782 : : /* ---------------------------------------------------------------------------------------------------- */
783 : :
784 : : static void
785 : 9 : replace (char *blob,
786 : : gsize len,
787 : : const char *before,
788 : : const char *after)
789 : : {
790 : : gsize i;
791 : 9 : gsize slen = strlen (before) + 1;
792 : :
793 : 9 : g_assert_cmpuint (strlen (before), ==, strlen (after));
794 : 9 : g_assert_cmpuint (len, >=, slen);
795 : :
796 : 621 : for (i = 0; i < (len - slen + 1); i++)
797 : : {
798 : 612 : if (memcmp (blob + i, before, slen) == 0)
799 : 3 : memcpy (blob + i, after, slen);
800 : : }
801 : 9 : }
802 : :
803 : : static void
804 : 1 : test_message_serialize_invalid (void)
805 : : {
806 : : guint n;
807 : :
808 : : /* Other things we could check (note that GDBus _does_ check for all
809 : : * these things - we just don't have test-suit coverage for it)
810 : : *
811 : : * - array exceeding 64 MiB (2^26 bytes) - unfortunately libdbus-1 checks
812 : : * this, e.g.
813 : : *
814 : : * process 19620: arguments to dbus_message_iter_append_fixed_array() were incorrect,
815 : : * assertion "n_elements <= DBUS_MAXIMUM_ARRAY_LENGTH / _dbus_type_get_alignment (element_type)"
816 : : * failed in file dbus-message.c line 2344.
817 : : * This is normally a bug in some application using the D-Bus library.
818 : : * D-Bus not built with -rdynamic so unable to print a backtrace
819 : : * Aborted (core dumped)
820 : : *
821 : : * - message exceeding 128 MiB (2^27 bytes)
822 : : *
823 : : * - endianness, message type, flags, protocol version
824 : : */
825 : :
826 : 4 : for (n = 0; n < 3; n++)
827 : : {
828 : : GDBusMessage *message;
829 : : GError *error;
830 : : DBusMessage *dbus_message;
831 : : char *blob;
832 : : int blob_len;
833 : : /* these are in pairs with matching length */
834 : 3 : const gchar *valid_utf8_str = "this is valid...";
835 : 3 : const gchar *invalid_utf8_str = "this is invalid\xff";
836 : 3 : const gchar *valid_signature = "a{sv}a{sv}a{sv}aiai";
837 : 3 : const gchar *invalid_signature = "not valid signature";
838 : 3 : const gchar *valid_object_path = "/this/is/a/valid/dbus/object/path";
839 : 3 : const gchar *invalid_object_path = "/this/is/not a valid object path!";
840 : :
841 : 3 : dbus_message = dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_CALL);
842 : 3 : dbus_message_set_serial (dbus_message, 0x41);
843 : 3 : dbus_message_set_path (dbus_message, "/foo/bar");
844 : 3 : dbus_message_set_member (dbus_message, "Member");
845 : 3 : switch (n)
846 : : {
847 : 1 : case 0:
848 : : /* invalid UTF-8 */
849 : 1 : dbus_message_append_args (dbus_message,
850 : : DBUS_TYPE_STRING, &valid_utf8_str,
851 : : DBUS_TYPE_INVALID);
852 : 1 : break;
853 : :
854 : 1 : case 1:
855 : : /* invalid object path */
856 : 1 : dbus_message_append_args (dbus_message,
857 : : DBUS_TYPE_OBJECT_PATH, &valid_object_path,
858 : : DBUS_TYPE_INVALID);
859 : 1 : break;
860 : :
861 : 1 : case 2:
862 : : /* invalid signature */
863 : 1 : dbus_message_append_args (dbus_message,
864 : : DBUS_TYPE_SIGNATURE, &valid_signature,
865 : : DBUS_TYPE_INVALID);
866 : 1 : break;
867 : :
868 : 0 : default:
869 : : g_assert_not_reached ();
870 : : break;
871 : : }
872 : 3 : dbus_message_marshal (dbus_message, &blob, &blob_len);
873 : : /* hack up the message to be invalid by replacing each valid string
874 : : * with its invalid counterpart */
875 : 3 : replace (blob, blob_len, valid_utf8_str, invalid_utf8_str);
876 : 3 : replace (blob, blob_len, valid_object_path, invalid_object_path);
877 : 3 : replace (blob, blob_len, valid_signature, invalid_signature);
878 : :
879 : 3 : error = NULL;
880 : 3 : message = g_dbus_message_new_from_blob ((guchar *) blob,
881 : : blob_len,
882 : : G_DBUS_CAPABILITY_FLAGS_NONE,
883 : : &error);
884 : 3 : g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
885 : 3 : g_error_free (error);
886 : 3 : g_assert (message == NULL);
887 : :
888 : 3 : dbus_free (blob);
889 : 3 : dbus_message_unref (dbus_message);
890 : : }
891 : :
892 : 1 : }
893 : :
894 : : /* ---------------------------------------------------------------------------------------------------- */
895 : :
896 : : static void
897 : 1 : test_message_serialize_header_checks (void)
898 : : {
899 : : GDBusMessage *message;
900 : : GDBusMessage *reply;
901 : 1 : GError *error = NULL;
902 : : guchar *blob;
903 : : gsize blob_size;
904 : :
905 : : /*
906 : : * check we can't serialize messages with INVALID type
907 : : */
908 : 1 : message = g_dbus_message_new ();
909 : 1 : blob = g_dbus_message_to_blob (message, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error);
910 : 1 : g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
911 : 1 : g_assert_cmpstr (error->message, ==, "Cannot serialize message: type is INVALID");
912 : 1 : g_clear_error (&error);
913 : 1 : g_assert_null (blob);
914 : 1 : g_object_unref (message);
915 : :
916 : : /*
917 : : * check we can't serialize messages with an INVALID header
918 : : */
919 : 1 : message = g_dbus_message_new_signal ("/the/path", "The.Interface", "TheMember");
920 : 1 : g_dbus_message_set_header (message, G_DBUS_MESSAGE_HEADER_FIELD_INVALID, g_variant_new_boolean (FALSE));
921 : 1 : blob = g_dbus_message_to_blob (message, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error);
922 : :
923 : 1 : g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
924 : 1 : g_assert_cmpstr (error->message, ==, "Cannot serialize message: SIGNAL message: INVALID header field supplied");
925 : 1 : g_assert_null (blob);
926 : :
927 : 1 : g_clear_error (&error);
928 : 1 : g_clear_object (&message);
929 : :
930 : : /*
931 : : * check that we can't serialize messages with various fields set to incorrectly typed values
932 : : */
933 : : const struct
934 : : {
935 : : GDBusMessageHeaderField field;
936 : : const char *invalid_value; /* as a GVariant in text form */
937 : : const char *expected_error_message;
938 : : }
939 : 1 : field_type_tests[] =
940 : : {
941 : : {
942 : : G_DBUS_MESSAGE_HEADER_FIELD_PATH,
943 : : "'/correct/value/but/wrong/type'",
944 : : "Cannot serialize message: SIGNAL message: PATH header field is invalid; expected a value of type ‘o’"
945 : : },
946 : : {
947 : : G_DBUS_MESSAGE_HEADER_FIELD_INTERFACE,
948 : : "@u 5",
949 : : "Cannot serialize message: SIGNAL message: INTERFACE header field is invalid; expected a value of type ‘s’"
950 : : },
951 : : {
952 : : G_DBUS_MESSAGE_HEADER_FIELD_INTERFACE,
953 : : "'valid type, but not an interface name'",
954 : : "Cannot serialize message: SIGNAL message: INTERFACE header field does not contain a valid interface name"
955 : : },
956 : : {
957 : : G_DBUS_MESSAGE_HEADER_FIELD_MEMBER,
958 : : "@u 5",
959 : : "Cannot serialize message: SIGNAL message: MEMBER header field is invalid; expected a value of type ‘s’"
960 : : },
961 : : {
962 : : G_DBUS_MESSAGE_HEADER_FIELD_MEMBER,
963 : : "'valid type, but not a member name'",
964 : : "Cannot serialize message: SIGNAL message: MEMBER header field does not contain a valid member name"
965 : : },
966 : : {
967 : : G_DBUS_MESSAGE_HEADER_FIELD_ERROR_NAME,
968 : : "@u 5",
969 : : "Cannot serialize message: SIGNAL message: ERROR_NAME header field is invalid; expected a value of type ‘s’"
970 : : },
971 : : {
972 : : G_DBUS_MESSAGE_HEADER_FIELD_ERROR_NAME,
973 : : "'valid type, but not an error name'",
974 : : "Cannot serialize message: SIGNAL message: ERROR_NAME header field does not contain a valid error name"
975 : : },
976 : : {
977 : : G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL,
978 : : "'oops'",
979 : : "Cannot serialize message: SIGNAL message: REPLY_SERIAL header field is invalid; expected a value of type ‘u’"
980 : : },
981 : : {
982 : : G_DBUS_MESSAGE_HEADER_FIELD_DESTINATION,
983 : : "@u 5",
984 : : "Cannot serialize message: SIGNAL message: DESTINATION header field is invalid; expected a value of type ‘s’"
985 : : },
986 : : {
987 : : G_DBUS_MESSAGE_HEADER_FIELD_SENDER,
988 : : "@u 5",
989 : : "Cannot serialize message: SIGNAL message: SENDER header field is invalid; expected a value of type ‘s’"
990 : : },
991 : : {
992 : : G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE,
993 : : "false",
994 : : "Cannot serialize message: SIGNAL message: SIGNATURE header field is invalid; expected a value of type ‘g’"
995 : : },
996 : : {
997 : : G_DBUS_MESSAGE_HEADER_FIELD_NUM_UNIX_FDS,
998 : : "'five'",
999 : : "Cannot serialize message: SIGNAL message: NUM_UNIX_FDS header field is invalid; expected a value of type ‘u’"
1000 : : },
1001 : : };
1002 : :
1003 : 13 : for (size_t i = 0; i < G_N_ELEMENTS (field_type_tests); i++)
1004 : : {
1005 : 12 : message = g_dbus_message_new_signal ("/the/path", "The.Interface", "TheMember");
1006 : 12 : g_dbus_message_set_header (message, field_type_tests[i].field, g_variant_new_parsed (field_type_tests[i].invalid_value));
1007 : 12 : blob = g_dbus_message_to_blob (message, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error);
1008 : :
1009 : 12 : g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
1010 : 12 : g_assert_cmpstr (error->message, ==, field_type_tests[i].expected_error_message);
1011 : 12 : g_assert_null (blob);
1012 : :
1013 : 12 : g_clear_error (&error);
1014 : 12 : g_clear_object (&message);
1015 : : }
1016 : :
1017 : : /*
1018 : : * check we can't serialize signal messages with INTERFACE, PATH or MEMBER unset / set to reserved value
1019 : : */
1020 : 1 : message = g_dbus_message_new_signal ("/the/path", "The.Interface", "TheMember");
1021 : : /* ----- */
1022 : : /* interface NULL => error */
1023 : 1 : g_dbus_message_set_interface (message, NULL);
1024 : 1 : blob = g_dbus_message_to_blob (message, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error);
1025 : 1 : g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
1026 : 1 : g_assert_cmpstr (error->message, ==, "Cannot serialize message: SIGNAL message: INTERFACE header field is missing or invalid");
1027 : 1 : g_clear_error (&error);
1028 : 1 : g_assert_null (blob);
1029 : : /* interface reserved value => error */
1030 : 1 : g_dbus_message_set_interface (message, DBUS_INTERFACE_LOCAL);
1031 : 1 : blob = g_dbus_message_to_blob (message, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error);
1032 : 1 : g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
1033 : 1 : g_assert_cmpstr (error->message, ==, "Cannot serialize message: SIGNAL message: INTERFACE header field is using the reserved value " DBUS_INTERFACE_LOCAL);
1034 : 1 : g_clear_error (&error);
1035 : 1 : g_assert_null (blob);
1036 : : /* reset interface */
1037 : 1 : g_dbus_message_set_interface (message, "The.Interface");
1038 : : /* ----- */
1039 : : /* path NULL => error */
1040 : 1 : g_dbus_message_set_path (message, NULL);
1041 : 1 : blob = g_dbus_message_to_blob (message, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error);
1042 : 1 : g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
1043 : 1 : g_assert_cmpstr (error->message, ==, "Cannot serialize message: SIGNAL message: PATH header field is missing or invalid");
1044 : 1 : g_clear_error (&error);
1045 : 1 : g_assert_null (blob);
1046 : : /* path reserved value => error */
1047 : 1 : g_dbus_message_set_path (message, DBUS_PATH_LOCAL);
1048 : 1 : blob = g_dbus_message_to_blob (message, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error);
1049 : 1 : g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
1050 : 1 : g_assert_cmpstr (error->message, ==, "Cannot serialize message: SIGNAL message: PATH header field is using the reserved value " DBUS_PATH_LOCAL);
1051 : 1 : g_clear_error (&error);
1052 : 1 : g_assert_null (blob);
1053 : : /* reset path */
1054 : 1 : g_dbus_message_set_path (message, "/the/path");
1055 : : /* ----- */
1056 : : /* member NULL => error */
1057 : 1 : g_dbus_message_set_member (message, NULL);
1058 : 1 : blob = g_dbus_message_to_blob (message, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error);
1059 : 1 : g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
1060 : 1 : g_assert_cmpstr (error->message, ==, "Cannot serialize message: SIGNAL message: MEMBER header field is missing or invalid");
1061 : 1 : g_clear_error (&error);
1062 : 1 : g_assert_null (blob);
1063 : : /* reset member */
1064 : 1 : g_dbus_message_set_member (message, "TheMember");
1065 : : /* ----- */
1066 : : /* done */
1067 : 1 : g_object_unref (message);
1068 : :
1069 : : /*
1070 : : * check that we can't serialize method call messages with PATH or MEMBER unset
1071 : : */
1072 : 1 : message = g_dbus_message_new_method_call (NULL, "/the/path", NULL, "TheMember");
1073 : : /* ----- */
1074 : : /* path NULL => error */
1075 : 1 : g_dbus_message_set_path (message, NULL);
1076 : 1 : blob = g_dbus_message_to_blob (message, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error);
1077 : 1 : g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
1078 : 1 : g_assert_cmpstr (error->message, ==, "Cannot serialize message: METHOD_CALL message: PATH header field is missing or invalid");
1079 : 1 : g_clear_error (&error);
1080 : 1 : g_assert_null (blob);
1081 : : /* reset path */
1082 : 1 : g_dbus_message_set_path (message, "/the/path");
1083 : : /* ----- */
1084 : : /* member NULL => error */
1085 : 1 : g_dbus_message_set_member (message, NULL);
1086 : 1 : blob = g_dbus_message_to_blob (message, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error);
1087 : 1 : g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
1088 : 1 : g_assert_cmpstr (error->message, ==, "Cannot serialize message: METHOD_CALL message: MEMBER header field is missing or invalid");
1089 : 1 : g_clear_error (&error);
1090 : 1 : g_assert_null (blob);
1091 : : /* reset member */
1092 : 1 : g_dbus_message_set_member (message, "TheMember");
1093 : : /* ----- */
1094 : : /* done */
1095 : 1 : g_object_unref (message);
1096 : :
1097 : : /*
1098 : : * check that we can't serialize method reply messages with REPLY_SERIAL unset
1099 : : */
1100 : 1 : message = g_dbus_message_new_method_call (NULL, "/the/path", NULL, "TheMember");
1101 : 1 : g_dbus_message_set_serial (message, 42);
1102 : : /* method reply */
1103 : 1 : reply = g_dbus_message_new_method_reply (message);
1104 : 1 : g_assert_cmpint (g_dbus_message_get_reply_serial (reply), ==, 42);
1105 : 1 : g_dbus_message_set_header (reply, G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL, NULL);
1106 : 1 : blob = g_dbus_message_to_blob (reply, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error);
1107 : 1 : g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
1108 : 1 : g_assert_cmpstr (error->message, ==, "Cannot serialize message: METHOD_RETURN message: REPLY_SERIAL header field is missing or invalid");
1109 : 1 : g_clear_error (&error);
1110 : 1 : g_assert_null (blob);
1111 : 1 : g_object_unref (reply);
1112 : : /* method error - first nuke ERROR_NAME, then REPLY_SERIAL */
1113 : 1 : reply = g_dbus_message_new_method_error (message, "Some.Error.Name", "the message");
1114 : 1 : g_assert_cmpint (g_dbus_message_get_reply_serial (reply), ==, 42);
1115 : : /* nuke ERROR_NAME */
1116 : 1 : g_dbus_message_set_error_name (reply, NULL);
1117 : 1 : blob = g_dbus_message_to_blob (reply, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error);
1118 : 1 : g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
1119 : 1 : g_assert_cmpstr (error->message, ==, "Cannot serialize message: ERROR message: ERROR_NAME header field is missing or invalid");
1120 : 1 : g_clear_error (&error);
1121 : 1 : g_assert_null (blob);
1122 : : /* reset ERROR_NAME */
1123 : 1 : g_dbus_message_set_error_name (reply, "Some.Error.Name");
1124 : : /* nuke REPLY_SERIAL */
1125 : 1 : g_dbus_message_set_header (reply, G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL, NULL);
1126 : 1 : blob = g_dbus_message_to_blob (reply, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error);
1127 : 1 : g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
1128 : 1 : g_assert_cmpstr (error->message, ==, "Cannot serialize message: ERROR message: REPLY_SERIAL header field is missing or invalid");
1129 : 1 : g_clear_error (&error);
1130 : 1 : g_assert_null (blob);
1131 : 1 : g_object_unref (reply);
1132 : 1 : g_object_unref (message);
1133 : 1 : }
1134 : :
1135 : : static void
1136 : 1 : test_message_serialize_header_checks_valid (void)
1137 : : {
1138 : 1 : GDBusMessage *message = NULL, *reply = NULL;
1139 : 1 : GError *local_error = NULL;
1140 : : guchar *blob;
1141 : : gsize blob_size;
1142 : :
1143 : 1 : g_test_summary ("Test that validation allows well-formed messages of all the different types");
1144 : :
1145 : : /* Method call */
1146 : 1 : message = g_dbus_message_new_method_call ("Some.Name", "/the/path", "org.some.Interface", "TheMethod");
1147 : 1 : g_dbus_message_set_serial (message, 666);
1148 : 1 : blob = g_dbus_message_to_blob (message, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &local_error);
1149 : 1 : g_assert_no_error (local_error);
1150 : 1 : g_assert_nonnull (blob);
1151 : 1 : g_free (blob);
1152 : :
1153 : : /* Method return */
1154 : 1 : reply = g_dbus_message_new_method_reply (message);
1155 : 1 : blob = g_dbus_message_to_blob (reply, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &local_error);
1156 : 1 : g_assert_no_error (local_error);
1157 : 1 : g_assert_nonnull (blob);
1158 : 1 : g_free (blob);
1159 : 1 : g_clear_object (&reply);
1160 : :
1161 : : /* Error */
1162 : 1 : reply = g_dbus_message_new_method_error (message, "Error.Name", "Some error message");
1163 : 1 : blob = g_dbus_message_to_blob (reply, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &local_error);
1164 : 1 : g_assert_no_error (local_error);
1165 : 1 : g_assert_nonnull (blob);
1166 : 1 : g_free (blob);
1167 : :
1168 : 1 : g_clear_object (&reply);
1169 : 1 : g_clear_object (&message);
1170 : :
1171 : : /* Signal */
1172 : 1 : message = g_dbus_message_new_signal ("/the/path", "org.some.Interface", "SignalName");
1173 : 1 : blob = g_dbus_message_to_blob (message, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &local_error);
1174 : 1 : g_assert_no_error (local_error);
1175 : 1 : g_assert_nonnull (blob);
1176 : 1 : g_free (blob);
1177 : 1 : g_clear_object (&message);
1178 : :
1179 : : /* Also check that an unknown message type is allowed */
1180 : 1 : message = g_dbus_message_new ();
1181 : 1 : g_dbus_message_set_message_type (message, 123);
1182 : 1 : blob = g_dbus_message_to_blob (message, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &local_error);
1183 : 1 : g_assert_no_error (local_error);
1184 : 1 : g_assert_nonnull (blob);
1185 : 1 : g_free (blob);
1186 : 1 : g_clear_object (&message);
1187 : :
1188 : : /* Even one with a well-defined field on it */
1189 : 1 : message = g_dbus_message_new ();
1190 : 1 : g_dbus_message_set_message_type (message, 123);
1191 : 1 : g_dbus_message_set_header (message, G_DBUS_MESSAGE_HEADER_FIELD_NUM_UNIX_FDS, g_variant_new_uint32 (0));
1192 : 1 : blob = g_dbus_message_to_blob (message, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &local_error);
1193 : 1 : g_assert_no_error (local_error);
1194 : 1 : g_assert_nonnull (blob);
1195 : 1 : g_free (blob);
1196 : 1 : g_clear_object (&message);
1197 : 1 : }
1198 : :
1199 : : /* ---------------------------------------------------------------------------------------------------- */
1200 : :
1201 : : static void
1202 : 1 : test_message_parse_empty_arrays_of_arrays (void)
1203 : : {
1204 : : GVariant *body;
1205 : 1 : GError *error = NULL;
1206 : :
1207 : 1 : g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=673612");
1208 : : /* These three-element array of empty arrays were previously read back as a
1209 : : * two-element array of empty arrays, due to sometimes erroneously skipping
1210 : : * four bytes to align for the eight-byte-aligned grandchild types (x and
1211 : : * dict_entry).
1212 : : */
1213 : 1 : body = g_variant_parse (G_VARIANT_TYPE ("(aaax)"),
1214 : : "([@aax [], [], []],)", NULL, NULL, &error);
1215 : 1 : g_assert_no_error (error);
1216 : 1 : check_serialization (body,
1217 : : "value 0: array:\n"
1218 : : " array:\n"
1219 : : " array:\n"
1220 : : " array:\n");
1221 : 1 : g_variant_unref (body);
1222 : :
1223 : 1 : body = g_variant_parse (G_VARIANT_TYPE ("(aaa{uu})"),
1224 : : "([@aa{uu} [], [], []],)", NULL, NULL, &error);
1225 : 1 : g_assert_no_error (error);
1226 : 1 : check_serialization (body,
1227 : : "value 0: array:\n"
1228 : : " array:\n"
1229 : : " array:\n"
1230 : : " array:\n");
1231 : 1 : g_variant_unref (body);
1232 : :
1233 : : /* Due to the same bug, g_dbus_message_new_from_blob() would fail for this
1234 : : * message because it would try to read past the end of the string. Hence,
1235 : : * sending this to an application would make it fall off the bus. */
1236 : 1 : body = g_variant_parse (G_VARIANT_TYPE ("(a(aa{sv}as))"),
1237 : : "([ ([], []),"
1238 : : " ([], []),"
1239 : : " ([], [])],)", NULL, NULL, &error);
1240 : 1 : g_assert_no_error (error);
1241 : 1 : check_serialization (body,
1242 : : "value 0: array:\n"
1243 : : " struct:\n"
1244 : : " array:\n"
1245 : : " array:\n"
1246 : : " struct:\n"
1247 : : " array:\n"
1248 : : " array:\n"
1249 : : " struct:\n"
1250 : : " array:\n"
1251 : : " array:\n");
1252 : 1 : g_variant_unref (body);
1253 : 1 : }
1254 : :
1255 : : /* ---------------------------------------------------------------------------------------------------- */
1256 : :
1257 : : static void
1258 : 1 : test_message_serialize_double_array (void)
1259 : : {
1260 : : GVariantBuilder builder;
1261 : : GVariant *body;
1262 : :
1263 : 1 : g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=732754");
1264 : :
1265 : 1 : g_variant_builder_init_static (&builder, G_VARIANT_TYPE ("ad"));
1266 : 1 : g_variant_builder_add (&builder, "d", (gdouble)0.0);
1267 : 1 : g_variant_builder_add (&builder, "d", (gdouble)8.0);
1268 : 1 : g_variant_builder_add (&builder, "d", (gdouble)22.0);
1269 : 1 : g_variant_builder_add (&builder, "d", (gdouble)0.0);
1270 : 1 : body = g_variant_new ("(@ad)", g_variant_builder_end (&builder));
1271 : 1 : check_serialization (body,
1272 : : "value 0: array:\n"
1273 : : " double: 0.000000\n"
1274 : : " double: 8.000000\n"
1275 : : " double: 22.000000\n"
1276 : : " double: 0.000000\n");
1277 : 1 : }
1278 : :
1279 : : /* ---------------------------------------------------------------------------------------------------- */
1280 : :
1281 : : /* Test that an invalid header in a D-Bus message (specifically, with a type
1282 : : * which doesn’t match what’s expected for the given header) is gracefully
1283 : : * handled with an error rather than a crash. */
1284 : : static void
1285 : 1 : test_message_parse_non_signature_header (void)
1286 : : {
1287 : 1 : const guint8 data[] = {
1288 : : 'l', /* little-endian byte order */
1289 : : 0x02, /* message type (method return) */
1290 : : 0x00, /* message flags (none) */
1291 : : 0x01, /* major protocol version */
1292 : : 0x00, 0x00, 0x00, 0x00, /* body length (in bytes) */
1293 : : 0x00, 0x00, 0x00, 0xbc, /* message serial */
1294 : : /* a{yv} of header fields:
1295 : : * (things start to be invalid below here) */
1296 : : 0x10, 0x00, 0x00, 0x00, /* array length (in bytes), must be a multiple of 8 */
1297 : : 0x08, /* array key (SIGNATURE) */
1298 : : /* Variant array value: */
1299 : : 0x04, /* signature length */
1300 : : 'd', 0x00, 0x00, 'F', /* signature (invalid) */
1301 : : 0x00, /* nul terminator */
1302 : : /* (Variant array value payload missing) */
1303 : : /* alignment padding before the next header array element, as structs must
1304 : : * be 8-aligned: */
1305 : : 0x00,
1306 : : 0x05, /* array key (REPLY_SERIAL, required for method return messages) */
1307 : : /* Variant array value: */
1308 : : 0x01, /* signature length */
1309 : : 'u', /* one complete type */
1310 : : 0x00, /* nul terminator */
1311 : : /* (Variant array value payload) */
1312 : : 0x00, 0x01, 0x02, 0x03,
1313 : : /* (message body is zero-length) */
1314 : : };
1315 : 1 : gsize size = sizeof (data);
1316 : 1 : GDBusMessage *message = NULL;
1317 : 1 : GError *local_error = NULL;
1318 : :
1319 : 1 : message = g_dbus_message_new_from_blob ((guchar *) data, size,
1320 : : G_DBUS_CAPABILITY_FLAGS_NONE,
1321 : : &local_error);
1322 : 1 : g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
1323 : 1 : g_assert_null (message);
1324 : :
1325 : 1 : g_clear_error (&local_error);
1326 : 1 : }
1327 : :
1328 : : /* ---------------------------------------------------------------------------------------------------- */
1329 : :
1330 : : /* Test that an invalid header in a D-Bus message (specifically, containing a
1331 : : * variant with an empty type signature) is gracefully handled with an error
1332 : : * rather than a crash. */
1333 : : static void
1334 : 1 : test_message_parse_empty_signature_header (void)
1335 : : {
1336 : 1 : const guint8 data[] = {
1337 : : 'l', /* little-endian byte order */
1338 : : 0x02, /* message type (method return) */
1339 : : 0x00, /* message flags (none) */
1340 : : 0x01, /* major protocol version */
1341 : : 0x00, 0x00, 0x00, 0x00, /* body length (in bytes) */
1342 : : 0x20, 0x20, 0x20, 0x20, /* message serial */
1343 : : /* a{yv} of header fields:
1344 : : * (things start to be invalid below here) */
1345 : : 0x10, 0x00, 0x00, 0x00, /* array length (in bytes), must be a multiple of 8 */
1346 : : 0x20, /* array key (this is not currently a valid header field) */
1347 : : /* Variant array value: */
1348 : : 0x00, /* signature length */
1349 : : 0x00, /* nul terminator */
1350 : : /* (Variant array value payload missing) */
1351 : : /* alignment padding before the next header array element, as structs must
1352 : : * be 8-aligned: */
1353 : : 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1354 : : 0x05, /* array key (REPLY_SERIAL, required for method return messages) */
1355 : : /* Variant array value: */
1356 : : 0x01, /* signature length */
1357 : : 'u', /* one complete type */
1358 : : 0x00, /* nul terminator */
1359 : : /* (Variant array value payload) */
1360 : : 0x00, 0x01, 0x02, 0x03,
1361 : : /* (message body is zero-length) */
1362 : : };
1363 : 1 : gsize size = sizeof (data);
1364 : 1 : GDBusMessage *message = NULL;
1365 : 1 : GError *local_error = NULL;
1366 : :
1367 : 1 : message = g_dbus_message_new_from_blob ((guchar *) data, size,
1368 : : G_DBUS_CAPABILITY_FLAGS_NONE,
1369 : : &local_error);
1370 : 1 : g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
1371 : 1 : g_assert_null (message);
1372 : :
1373 : 1 : g_clear_error (&local_error);
1374 : 1 : }
1375 : :
1376 : : /* ---------------------------------------------------------------------------------------------------- */
1377 : :
1378 : : /* Test that an invalid header in a D-Bus message (specifically, containing a
1379 : : * variant with a type signature containing multiple complete types) is
1380 : : * gracefully handled with an error rather than a crash. */
1381 : : static void
1382 : 1 : test_message_parse_multiple_signature_header (void)
1383 : : {
1384 : 1 : const guint8 data[] = {
1385 : : 'l', /* little-endian byte order */
1386 : : 0x02, /* message type (method return) */
1387 : : 0x00, /* message flags (none) */
1388 : : 0x01, /* major protocol version */
1389 : : 0x00, 0x00, 0x00, 0x00, /* body length (in bytes) */
1390 : : 0x20, 0x20, 0x20, 0x20, /* message serial */
1391 : : /* a{yv} of header fields:
1392 : : * (things start to be invalid below here) */
1393 : : 0x10, 0x00, 0x00, 0x00, /* array length (in bytes), must be a multiple of 8 */
1394 : : 0x20, /* array key (this is not currently a valid header field) */
1395 : : /* Variant array value: */
1396 : : 0x02, /* signature length */
1397 : : 'b', 'b', /* two complete types */
1398 : : 0x00, /* nul terminator */
1399 : : /* (Variant array value payload missing) */
1400 : : /* alignment padding before the next header array element, as structs must
1401 : : * be 8-aligned: */
1402 : : 0x00, 0x00, 0x00,
1403 : : 0x05, /* array key (REPLY_SERIAL, required for method return messages) */
1404 : : /* Variant array value: */
1405 : : 0x01, /* signature length */
1406 : : 'u', /* one complete type */
1407 : : 0x00, /* nul terminator */
1408 : : /* (Variant array value payload) */
1409 : : 0x00, 0x01, 0x02, 0x03,
1410 : : /* (message body is zero-length) */
1411 : : };
1412 : 1 : gsize size = sizeof (data);
1413 : 1 : GDBusMessage *message = NULL;
1414 : 1 : GError *local_error = NULL;
1415 : :
1416 : 1 : message = g_dbus_message_new_from_blob ((guchar *) data, size,
1417 : : G_DBUS_CAPABILITY_FLAGS_NONE,
1418 : : &local_error);
1419 : 1 : g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
1420 : 1 : g_assert_null (message);
1421 : :
1422 : 1 : g_clear_error (&local_error);
1423 : 1 : }
1424 : :
1425 : : /* ---------------------------------------------------------------------------------------------------- */
1426 : :
1427 : : /* Test that an invalid header in a D-Bus message (specifically, containing a
1428 : : * variant with a valid type signature that is too long to be a valid
1429 : : * #GVariantType due to exceeding the array nesting limits) is gracefully
1430 : : * handled with an error rather than a crash. */
1431 : : static void
1432 : 1 : test_message_parse_over_long_signature_header (void)
1433 : : {
1434 : 1 : const guint8 data[] = {
1435 : : 'l', /* little-endian byte order */
1436 : : 0x02, /* message type (method return) */
1437 : : 0x00, /* message flags (none) */
1438 : : 0x01, /* major protocol version */
1439 : : 0x00, 0x00, 0x00, 0x00, /* body length (in bytes) */
1440 : : 0x20, 0x20, 0x20, 0x20, /* message serial */
1441 : : /* a{yv} of header fields:
1442 : : * (things start to be invalid below here) */
1443 : : 0xa0, 0x00, 0x00, 0x00, /* array length (in bytes), must be a multiple of 8 */
1444 : : 0x08, /* array key (SIGNATURE) */
1445 : : /* Variant array value: */
1446 : : 0x04, /* signature length */
1447 : : 'g', 0x00, 0x20, 0x20, /* one complete type plus some rubbish */
1448 : : 0x00, /* nul terminator */
1449 : : /* (Variant array value payload) */
1450 : : /* Critically, this contains 128 nested ‘a’s, which exceeds
1451 : : * %G_VARIANT_MAX_RECURSION_DEPTH. */
1452 : : 0xec,
1453 : : 'a', 'b', 'g', 'd', 'u', 'd', 'd', 'd', 'd', 'd', 'd', 'd',
1454 : : 'd', 'd', 'd',
1455 : : 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
1456 : : 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
1457 : : 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
1458 : : 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
1459 : : 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
1460 : : 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
1461 : : 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
1462 : : 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
1463 : : 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
1464 : : 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
1465 : : 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
1466 : : 'v',
1467 : : /* first header length is a multiple of 8 so no padding is needed */
1468 : : 0x05, /* array key (REPLY_SERIAL, required for method return messages) */
1469 : : /* Variant array value: */
1470 : : 0x01, /* signature length */
1471 : : 'u', /* one complete type */
1472 : : 0x00, /* nul terminator */
1473 : : /* (Variant array value payload) */
1474 : : 0x00, 0x01, 0x02, 0x03,
1475 : : /* (message body is zero-length) */
1476 : : };
1477 : 1 : gsize size = sizeof (data);
1478 : 1 : GDBusMessage *message = NULL;
1479 : 1 : GError *local_error = NULL;
1480 : :
1481 : 1 : message = g_dbus_message_new_from_blob ((guchar *) data, size,
1482 : : G_DBUS_CAPABILITY_FLAGS_NONE,
1483 : : &local_error);
1484 : 1 : g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
1485 : 1 : g_assert_null (message);
1486 : :
1487 : 1 : g_clear_error (&local_error);
1488 : 1 : }
1489 : :
1490 : : /* ---------------------------------------------------------------------------------------------------- */
1491 : :
1492 : : /* Test that an invalid header in a D-Bus message (specifically, containing too
1493 : : * many levels of nested variant) is gracefully handled with an error rather
1494 : : * than a crash. */
1495 : : static void
1496 : 1 : test_message_parse_deep_header_nesting (void)
1497 : : {
1498 : 1 : const guint8 data[] = {
1499 : : 'l', /* little-endian byte order */
1500 : : 0x02, /* message type (method return) */
1501 : : 0x00, /* message flags (none) */
1502 : : 0x01, /* major protocol version */
1503 : : 0x00, 0x00, 0x00, 0x00, /* body length (in bytes) */
1504 : : 0x20, 0x20, 0x20, 0x20, /* message serial */
1505 : : /* a{yv} of header fields:
1506 : : * (things start to be invalid below here) */
1507 : : 0xd0, 0x00, 0x00, 0x00, /* array length (in bytes), must be a multiple of 8 */
1508 : : 0x20, /* array key (this is not currently a valid header field) */
1509 : : /* Variant array value: */
1510 : : 0x01, /* signature length */
1511 : : 'v', /* one complete type */
1512 : : 0x00, /* nul terminator */
1513 : : /* (Variant array value payload) */
1514 : : /* Critically, this contains 64 nested variants (minus two for the
1515 : : * ‘arbitrary valid content’ below, but ignoring two for the `a{yv}`
1516 : : * above), which in total exceeds %G_DBUS_MAX_TYPE_DEPTH. */
1517 : : 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00,
1518 : : 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00,
1519 : : 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00,
1520 : : 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00,
1521 : : 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00,
1522 : : 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00,
1523 : : 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00,
1524 : : 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00,
1525 : : 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00,
1526 : : 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00,
1527 : : 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00,
1528 : : 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00,
1529 : : 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00,
1530 : : 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00,
1531 : : 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00,
1532 : : 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00,
1533 : : /* Some arbitrary valid content inside the innermost variant: */
1534 : : 0x01, 'y', 0x00, 0xcc,
1535 : : /* no padding needed as this header element length is a multiple of 8 */
1536 : : 0x05, /* array key (REPLY_SERIAL, required for method return messages) */
1537 : : /* Variant array value: */
1538 : : 0x01, /* signature length */
1539 : : 'u', /* one complete type */
1540 : : 0x00, /* nul terminator */
1541 : : /* (Variant array value payload) */
1542 : : 0x00, 0x01, 0x02, 0x03,
1543 : : /* (message body is zero-length) */
1544 : : };
1545 : 1 : gsize size = sizeof (data);
1546 : 1 : GDBusMessage *message = NULL;
1547 : 1 : GError *local_error = NULL;
1548 : :
1549 : 1 : message = g_dbus_message_new_from_blob ((guchar *) data, size,
1550 : : G_DBUS_CAPABILITY_FLAGS_NONE,
1551 : : &local_error);
1552 : 1 : g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
1553 : 1 : g_assert_null (message);
1554 : :
1555 : 1 : g_clear_error (&local_error);
1556 : 1 : }
1557 : :
1558 : : /* ---------------------------------------------------------------------------------------------------- */
1559 : :
1560 : : /* Test that an invalid body in a D-Bus message (specifically, containing too
1561 : : * many levels of nested variant) is gracefully handled with an error rather
1562 : : * than a crash. The set of bytes here are a modified version of the bytes from
1563 : : * test_message_parse_deep_header_nesting(). */
1564 : : static void
1565 : 1 : test_message_parse_deep_body_nesting (void)
1566 : : {
1567 : 1 : const guint8 data[] = {
1568 : : 'l', /* little-endian byte order */
1569 : : 0x02, /* message type (method return) */
1570 : : 0x00, /* message flags (none) */
1571 : : 0x01, /* major protocol version */
1572 : : 0xc4, 0x00, 0x00, 0x00, /* body length (in bytes) */
1573 : : 0x20, 0x20, 0x20, 0x20, /* message serial */
1574 : : /* a{yv} of header fields: */
1575 : : 0x10, 0x00, 0x00, 0x00, /* array length (in bytes), must be a multiple of 8 */
1576 : : 0x08, /* array key (SIGNATURE) */
1577 : : /* Variant array value: */
1578 : : 0x01, /* signature length */
1579 : : 'g', /* one complete type */
1580 : : 0x00, /* nul terminator */
1581 : : /* (Variant array value payload) */
1582 : : 0x01, 'v', 0x00,
1583 : : /* alignment padding before the next header array element, as structs must
1584 : : * be 8-aligned: */
1585 : : 0x00,
1586 : : 0x05, /* array key (REPLY_SERIAL, required for method return messages) */
1587 : : /* Variant array value: */
1588 : : 0x01, /* signature length */
1589 : : 'u', /* one complete type */
1590 : : 0x00, /* nul terminator */
1591 : : /* (Variant array value payload) */
1592 : : 0x00, 0x01, 0x02, 0x03,
1593 : : /* Message body: over 64 levels of nested variant, which is not valid: */
1594 : : 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00,
1595 : : 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00,
1596 : : 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00,
1597 : : 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00,
1598 : : 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00,
1599 : : 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00,
1600 : : 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00,
1601 : : 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00,
1602 : : 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00,
1603 : : 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00,
1604 : : 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00,
1605 : : 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00,
1606 : : 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00,
1607 : : 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00,
1608 : : 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00,
1609 : : 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00,
1610 : : /* Some arbitrary valid content inside the innermost variant: */
1611 : : 0x01, 'y', 0x00, 0xcc,
1612 : : };
1613 : 1 : gsize size = sizeof (data);
1614 : 1 : GDBusMessage *message = NULL;
1615 : 1 : GError *local_error = NULL;
1616 : :
1617 : 1 : message = g_dbus_message_new_from_blob ((guchar *) data, size,
1618 : : G_DBUS_CAPABILITY_FLAGS_NONE,
1619 : : &local_error);
1620 : 1 : g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
1621 : 1 : g_assert_null (message);
1622 : :
1623 : 1 : g_clear_error (&local_error);
1624 : 1 : }
1625 : :
1626 : : /* ---------------------------------------------------------------------------------------------------- */
1627 : :
1628 : : static void
1629 : 1 : test_message_parse_truncated (void)
1630 : : {
1631 : 1 : GDBusMessage *message = NULL;
1632 : 1 : GDBusMessage *message2 = NULL;
1633 : : GVariantBuilder builder;
1634 : 1 : guchar *blob = NULL;
1635 : 1 : gsize size = 0;
1636 : 1 : GError *error = NULL;
1637 : :
1638 : 1 : g_test_summary ("Test that truncated messages are properly rejected.");
1639 : 1 : g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/2528");
1640 : :
1641 : 1 : message = g_dbus_message_new ();
1642 : 1 : g_variant_builder_init_static (&builder, G_VARIANT_TYPE ("(asbynqiuxtd)"));
1643 : 1 : g_variant_builder_open (&builder, G_VARIANT_TYPE ("as"));
1644 : 1 : g_variant_builder_add (&builder, "s", "fourtytwo");
1645 : 1 : g_variant_builder_close (&builder);
1646 : 1 : g_variant_builder_add (&builder, "b", TRUE);
1647 : 1 : g_variant_builder_add (&builder, "y", 42);
1648 : 1 : g_variant_builder_add (&builder, "n", 42);
1649 : 1 : g_variant_builder_add (&builder, "q", 42);
1650 : 1 : g_variant_builder_add (&builder, "i", 42);
1651 : 1 : g_variant_builder_add (&builder, "u", 42);
1652 : 1 : g_variant_builder_add (&builder, "x", 42);
1653 : 1 : g_variant_builder_add (&builder, "t", 42);
1654 : 1 : g_variant_builder_add (&builder, "d", (gdouble) 42);
1655 : :
1656 : 1 : g_dbus_message_set_message_type (message, G_DBUS_MESSAGE_TYPE_METHOD_CALL);
1657 : 1 : g_dbus_message_set_header (message, G_DBUS_MESSAGE_HEADER_FIELD_PATH,
1658 : : g_variant_new_object_path ("/foo/bar"));
1659 : 1 : g_dbus_message_set_header (message, G_DBUS_MESSAGE_HEADER_FIELD_MEMBER,
1660 : : g_variant_new_string ("Member"));
1661 : 1 : g_dbus_message_set_body (message, g_variant_builder_end (&builder));
1662 : :
1663 : 1 : blob = g_dbus_message_to_blob (message, &size, G_DBUS_CAPABILITY_FLAGS_NONE, &error);
1664 : 1 : g_assert_no_error (error);
1665 : :
1666 : 1 : g_clear_object (&message);
1667 : :
1668 : : /* Try parsing all possible prefixes of the full @blob. */
1669 : 145 : for (gsize i = 0; i < size; i++)
1670 : : {
1671 : 144 : message2 = g_dbus_message_new_from_blob (blob, i, G_DBUS_CAPABILITY_FLAGS_NONE, &error);
1672 : 144 : g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
1673 : 144 : g_assert_null (message2);
1674 : 144 : g_clear_error (&error);
1675 : : }
1676 : :
1677 : 1 : message2 = g_dbus_message_new_from_blob (blob, size, G_DBUS_CAPABILITY_FLAGS_NONE, &error);
1678 : 1 : g_assert_no_error (error);
1679 : 1 : g_assert_true (G_IS_DBUS_MESSAGE (message2));
1680 : 1 : g_clear_object (&message2);
1681 : :
1682 : 1 : g_free (blob);
1683 : 1 : }
1684 : :
1685 : : static void
1686 : 1 : test_message_parse_empty_structure (void)
1687 : : {
1688 : 1 : const guint8 data[] =
1689 : : {
1690 : : 'l', /* little-endian byte order */
1691 : : 0x02, /* message type (method return) */
1692 : : 0x00, /* message flags (none) */
1693 : : 0x01, /* major protocol version */
1694 : : 0x08, 0x00, 0x00, 0x00, /* body length (in bytes) */
1695 : : 0x00, 0x00, 0x00, 0x00, /* message serial */
1696 : : /* a{yv} of header fields */
1697 : : 0x20, 0x00, 0x00, 0x00, /* array length (in bytes), must be a multiple of 8 */
1698 : : 0x01, /* array key (PATH) */
1699 : : 0x01, /* signature length */
1700 : : 'o', /* type (OBJECT_PATH) */
1701 : : 0x00, /* nul terminator */
1702 : : 0x05, 0x00, 0x00, 0x00, /* length 5 */
1703 : : '/', 'p', 'a', 't', 'h', 0x00, 0x00, 0x00, /* string '/path' and padding */
1704 : : 0x03, /* array key (MEMBER) */
1705 : : 0x01, /* signature length */
1706 : : 's', /* type (STRING) */
1707 : : 0x00, /* nul terminator */
1708 : : 0x06, 0x00, 0x00, 0x00, /* length 6 */
1709 : : 'M', 'e', 'm', 'b', 'e', 'r', 0x00, 0x00, /* string 'Member' and padding */
1710 : : 0x08, /* array key (SIGNATURE) */
1711 : : 0x01, /* signature length */
1712 : : 'g', /* type (SIGNATURE) */
1713 : : 0x00, /* nul terminator */
1714 : : 0x03, /* length 3 */
1715 : : 'a', '(', ')', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* type 'a()' and padding */
1716 : : 0x08, 0x00, 0x00, 0x00, /* array length: 4 bytes */
1717 : : 0x00, 0x00, 0x00, 0x00, /* padding to 8 bytes */
1718 : : 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* array data */
1719 : : 0x00
1720 : : };
1721 : 1 : gsize size = sizeof (data);
1722 : 1 : GDBusMessage *message = NULL;
1723 : 1 : GError *local_error = NULL;
1724 : :
1725 : 1 : g_test_summary ("Test that empty structures are rejected when parsing.");
1726 : 1 : g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/2557");
1727 : :
1728 : 1 : message = g_dbus_message_new_from_blob ((guchar *) data, size,
1729 : : G_DBUS_CAPABILITY_FLAGS_NONE,
1730 : : &local_error);
1731 : 1 : g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
1732 : 1 : g_assert_cmpstr (local_error->message, ==, "Empty structures (tuples) are not allowed in D-Bus");
1733 : 1 : g_assert_null (message);
1734 : :
1735 : 1 : g_clear_error (&local_error);
1736 : 1 : }
1737 : :
1738 : : static void
1739 : 1 : test_message_serialize_empty_structure (void)
1740 : : {
1741 : : GDBusMessage *message;
1742 : : GVariantBuilder builder;
1743 : 1 : gsize size = 0;
1744 : 1 : GError *local_error = NULL;
1745 : :
1746 : 1 : g_test_summary ("Test that empty structures are rejected when serializing.");
1747 : 1 : g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/2557");
1748 : :
1749 : 1 : message = g_dbus_message_new ();
1750 : 1 : g_variant_builder_init_static (&builder, G_VARIANT_TYPE ("(a())"));
1751 : 1 : g_variant_builder_open (&builder, G_VARIANT_TYPE ("a()"));
1752 : 1 : g_variant_builder_add (&builder, "()");
1753 : 1 : g_variant_builder_close (&builder);
1754 : 1 : g_dbus_message_set_message_type (message, G_DBUS_MESSAGE_TYPE_METHOD_CALL);
1755 : 1 : g_dbus_message_set_header (message, G_DBUS_MESSAGE_HEADER_FIELD_PATH,
1756 : : g_variant_new_object_path ("/path"));
1757 : 1 : g_dbus_message_set_header (message, G_DBUS_MESSAGE_HEADER_FIELD_MEMBER,
1758 : : g_variant_new_string ("Member"));
1759 : 1 : g_dbus_message_set_body (message, g_variant_builder_end (&builder));
1760 : :
1761 : 1 : g_dbus_message_to_blob (message, &size, G_DBUS_CAPABILITY_FLAGS_NONE, &local_error);
1762 : 1 : g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
1763 : 1 : g_assert_cmpstr (local_error->message, ==, "Empty structures (tuples) are not allowed in D-Bus");
1764 : :
1765 : 1 : g_clear_error (&local_error);
1766 : 1 : g_clear_object (&message);
1767 : 1 : }
1768 : :
1769 : : static void
1770 : 1 : test_message_parse_missing_header (void)
1771 : : {
1772 : 1 : const guint8 data[] = {
1773 : : 'l', /* little-endian byte order */
1774 : : 0x01, /* message type (method call) */
1775 : : 0x00, /* message flags (none) */
1776 : : 0x01, /* major protocol version */
1777 : : 0x12, 0x00, 0x00, 0x00, /* body length (in bytes) */
1778 : : 0x20, 0x20, 0x20, 0x20, /* message serial */
1779 : : /* a{yv} of header fields: */
1780 : : 0x24, 0x00, 0x00, 0x00, /* array length (in bytes), must be a multiple of 8 */
1781 : : 0x01, /* array key (PATH, required for method call messages) */
1782 : : /* Variant array value: */
1783 : : 0x01, /* signature length */
1784 : : 'o', /* one complete type */
1785 : : 0x00, /* nul terminator */
1786 : : /* (Variant array value payload) */
1787 : : 0x01, 0x00, 0x00, 0x00,
1788 : : '/', 0x00, 0x00, 0x00,
1789 : : 0x00, 0x00, 0x00, 0x00,
1790 : : 0x30, /* array key (MEMBER, required for method call messages; CORRUPTED from 0x03) */
1791 : : /* Variant array value: */
1792 : : 0x01, /* signature length */
1793 : : 's', /* one complete type */
1794 : : 0x00, /* nul terminator */
1795 : : /* (Variant array value payload) */
1796 : : 0x03, 0x00, 0x00, 0x00,
1797 : : 'H', 'e', 'y', 0x00,
1798 : : 0x00, 0x00, 0x00, 0x00,
1799 : : 0x08, /* array key (SIGNATURE) */
1800 : : /* Variant array value: */
1801 : : 0x01, /* signature length */
1802 : : 'g', /* one complete type */
1803 : : 0x00, /* nul terminator */
1804 : : /* (Variant array value payload) */
1805 : : 0x02, 's', 's', 0x00,
1806 : : /* Some arbitrary valid content inside the message body: */
1807 : : 0x03, 0x00, 0x00, 0x00,
1808 : : 'h', 'e', 'y', 0x00,
1809 : : 0x05, 0x00, 0x00, 0x00,
1810 : : 't', 'h', 'e', 'r', 'e', 0x00
1811 : : };
1812 : :
1813 : 1 : gsize size = sizeof (data);
1814 : 1 : GDBusMessage *message = NULL;
1815 : 1 : GError *local_error = NULL;
1816 : :
1817 : 1 : g_test_summary ("Test that missing (required) headers prompt an error.");
1818 : 1 : g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/3061");
1819 : :
1820 : 1 : message = g_dbus_message_new_from_blob ((guchar *) data, size,
1821 : : G_DBUS_CAPABILITY_FLAGS_NONE,
1822 : : &local_error);
1823 : 1 : g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
1824 : 1 : g_assert_null (message);
1825 : :
1826 : 1 : g_clear_error (&local_error);
1827 : 1 : }
1828 : :
1829 : : static void
1830 : 1 : test_message_parse_invalid_header_type (void)
1831 : : {
1832 : 1 : const guint8 data[] = {
1833 : : 'l', /* little-endian byte order */
1834 : : 0x01, /* message type (method call) */
1835 : : 0x00, /* message flags (none) */
1836 : : 0x01, /* major protocol version */
1837 : : 0x12, 0x00, 0x00, 0x00, /* body length (in bytes) */
1838 : : 0x20, 0x20, 0x20, 0x20, /* message serial */
1839 : : /* a{yv} of header fields: */
1840 : : 0x24, 0x00, 0x00, 0x00, /* array length (in bytes), must be a multiple of 8 */
1841 : : 0x01, /* array key (PATH, required for method call messages) */
1842 : : /* Variant array value: */
1843 : : 0x01, /* signature length */
1844 : : 'o', /* one complete type */
1845 : : 0x00, /* nul terminator */
1846 : : /* (Variant array value payload) */
1847 : : 0x01, 0x00, 0x00, 0x00,
1848 : : '/', 0x00, 0x00, 0x00,
1849 : : 0x00, 0x00, 0x00, 0x00,
1850 : : 0x03, /* array key (MEMBER, required for method call messages) */
1851 : : /* Variant array value: */
1852 : : 0x01, /* signature length */
1853 : : 't', /* one complete type; CORRUPTED, MEMBER should be 's' */
1854 : : 0x00, /* nul terminator */
1855 : : /* (Padding to 64-bit alignment of 't)' */
1856 : : 0x00, 0x00, 0x00, 0x00,
1857 : : /* (Variant array value payload) */
1858 : : 'H', 'e', 'y', 0x00,
1859 : : 0x00, 0x00, 0x00, 0x00,
1860 : : 0x08, /* array key (SIGNATURE) */
1861 : : /* Variant array value: */
1862 : : 0x01, /* signature length */
1863 : : 'g', /* one complete type */
1864 : : 0x00, /* nul terminator */
1865 : : /* (Variant array value payload) */
1866 : : 0x02, 's', 's', 0x00,
1867 : : /* Some arbitrary valid content inside the message body: */
1868 : : 0x03, 0x00, 0x00, 0x00,
1869 : : 'h', 'e', 'y', 0x00,
1870 : : 0x05, 0x00, 0x00, 0x00,
1871 : : 't', 'h', 'e', 'r', 'e', 0x00
1872 : : };
1873 : :
1874 : 1 : gsize size = sizeof (data);
1875 : 1 : GDBusMessage *message = NULL;
1876 : 1 : GError *local_error = NULL;
1877 : :
1878 : 1 : g_test_summary ("Test that the type of well-known headers is checked.");
1879 : 1 : g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/3061");
1880 : :
1881 : 1 : message = g_dbus_message_new_from_blob ((guchar *) data, size,
1882 : : G_DBUS_CAPABILITY_FLAGS_NONE,
1883 : : &local_error);
1884 : 1 : g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
1885 : 1 : g_assert_null (message);
1886 : :
1887 : 1 : g_clear_error (&local_error);
1888 : 1 : }
1889 : :
1890 : : /* ---------------------------------------------------------------------------------------------------- */
1891 : :
1892 : : int
1893 : 1 : main (int argc,
1894 : : char *argv[])
1895 : : {
1896 : 1 : g_setenv ("LC_ALL", "C", TRUE);
1897 : 1 : setlocale (LC_ALL, "C");
1898 : :
1899 : 1 : g_test_init (&argc, &argv, G_TEST_OPTION_ISOLATE_DIRS, NULL);
1900 : :
1901 : 1 : g_test_add_func ("/gdbus/message-serialize/basic",
1902 : : test_message_serialize_basic);
1903 : 1 : g_test_add_func ("/gdbus/message-serialize/complex",
1904 : : test_message_serialize_complex);
1905 : 1 : g_test_add_func ("/gdbus/message-serialize/invalid",
1906 : : test_message_serialize_invalid);
1907 : 1 : g_test_add_func ("/gdbus/message-serialize/header-checks",
1908 : : test_message_serialize_header_checks);
1909 : 1 : g_test_add_func ("/gdbus/message-serialize/header-checks/valid",
1910 : : test_message_serialize_header_checks_valid);
1911 : 1 : g_test_add_func ("/gdbus/message-serialize/double-array",
1912 : : test_message_serialize_double_array);
1913 : 1 : g_test_add_func ("/gdbus/message-serialize/empty-structure",
1914 : : test_message_serialize_empty_structure);
1915 : :
1916 : 1 : g_test_add_func ("/gdbus/message-parse/empty-arrays-of-arrays",
1917 : : test_message_parse_empty_arrays_of_arrays);
1918 : 1 : g_test_add_func ("/gdbus/message-parse/non-signature-header",
1919 : : test_message_parse_non_signature_header);
1920 : 1 : g_test_add_func ("/gdbus/message-parse/empty-signature-header",
1921 : : test_message_parse_empty_signature_header);
1922 : 1 : g_test_add_func ("/gdbus/message-parse/multiple-signature-header",
1923 : : test_message_parse_multiple_signature_header);
1924 : 1 : g_test_add_func ("/gdbus/message-parse/over-long-signature-header",
1925 : : test_message_parse_over_long_signature_header);
1926 : 1 : g_test_add_func ("/gdbus/message-parse/deep-header-nesting",
1927 : : test_message_parse_deep_header_nesting);
1928 : 1 : g_test_add_func ("/gdbus/message-parse/deep-body-nesting",
1929 : : test_message_parse_deep_body_nesting);
1930 : 1 : g_test_add_func ("/gdbus/message-parse/truncated",
1931 : : test_message_parse_truncated);
1932 : 1 : g_test_add_func ("/gdbus/message-parse/empty-structure",
1933 : : test_message_parse_empty_structure);
1934 : 1 : g_test_add_func ("/gdbus/message-parse/missing-header",
1935 : : test_message_parse_missing_header);
1936 : 1 : g_test_add_func ("/gdbus/message-parse/invalid-header-type",
1937 : : test_message_parse_invalid_header_type);
1938 : :
1939 : 1 : return g_test_run();
1940 : : }
|