gvariant: Fix bounds checking in GVariant text format parser
[glib.git] / glib / tests / gvariant.c
blob5aac3de53366e850dcd5d71e3c95671cc56b6c18
1 /*
2 * Copyright © 2010 Codethink Limited
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * See the included COPYING file for more information.
11 * Author: Ryan Lortie <desrt@desrt.ca>
14 #include "config.h"
16 #include <glib/gvariant-internal.h>
17 #include <string.h>
18 #include <stdlib.h>
19 #include <glib.h>
21 #define BASIC "bynqiuxthdsog?"
22 #define N_BASIC (G_N_ELEMENTS (BASIC) - 1)
24 #define INVALIDS "cefjklpwz&@^$"
25 #define N_INVALIDS (G_N_ELEMENTS (INVALIDS) - 1)
27 /* see comment in gvariant-serialiser.c about this madness.
29 * we use this to get testing of non-strictly-aligned GVariant instances
30 * on machines that can tolerate it. it is necessary to support this
31 * because some systems have malloc() that returns non-8-aligned
32 * pointers. it is necessary to have special support in the tests
33 * because on most machines malloc() is 8-aligned.
35 #define ALIGN_BITS (sizeof (struct { char a; union { \
36 guint64 x; void *y; gdouble z; } b; }) - 9)
38 static gboolean
39 randomly (gdouble prob)
41 return g_test_rand_double_range (0, 1) < prob;
44 /* corecursion */
45 static GVariantType *
46 append_tuple_type_string (GString *, GString *, gboolean, gint);
48 /* append a random GVariantType to a GString
49 * append a description of the type to another GString
50 * return what the type is
52 static GVariantType *
53 append_type_string (GString *string,
54 GString *description,
55 gboolean definite,
56 gint depth)
58 if (!depth-- || randomly (0.3))
60 gchar b = BASIC[g_test_rand_int_range (0, N_BASIC - definite)];
61 g_string_append_c (string, b);
62 g_string_append_c (description, b);
64 switch (b)
66 case 'b':
67 return g_variant_type_copy (G_VARIANT_TYPE_BOOLEAN);
68 case 'y':
69 return g_variant_type_copy (G_VARIANT_TYPE_BYTE);
70 case 'n':
71 return g_variant_type_copy (G_VARIANT_TYPE_INT16);
72 case 'q':
73 return g_variant_type_copy (G_VARIANT_TYPE_UINT16);
74 case 'i':
75 return g_variant_type_copy (G_VARIANT_TYPE_INT32);
76 case 'u':
77 return g_variant_type_copy (G_VARIANT_TYPE_UINT32);
78 case 'x':
79 return g_variant_type_copy (G_VARIANT_TYPE_INT64);
80 case 't':
81 return g_variant_type_copy (G_VARIANT_TYPE_UINT64);
82 case 'h':
83 return g_variant_type_copy (G_VARIANT_TYPE_HANDLE);
84 case 'd':
85 return g_variant_type_copy (G_VARIANT_TYPE_DOUBLE);
86 case 's':
87 return g_variant_type_copy (G_VARIANT_TYPE_STRING);
88 case 'o':
89 return g_variant_type_copy (G_VARIANT_TYPE_OBJECT_PATH);
90 case 'g':
91 return g_variant_type_copy (G_VARIANT_TYPE_SIGNATURE);
92 case '?':
93 return g_variant_type_copy (G_VARIANT_TYPE_BASIC);
94 default:
95 g_assert_not_reached ();
98 else
100 GVariantType *result;
102 switch (g_test_rand_int_range (0, definite ? 5 : 7))
104 case 0:
106 GVariantType *element;
108 g_string_append_c (string, 'a');
109 g_string_append (description, "a of ");
110 element = append_type_string (string, description,
111 definite, depth);
112 result = g_variant_type_new_array (element);
113 g_variant_type_free (element);
116 g_assert (g_variant_type_is_array (result));
117 break;
119 case 1:
121 GVariantType *element;
123 g_string_append_c (string, 'm');
124 g_string_append (description, "m of ");
125 element = append_type_string (string, description,
126 definite, depth);
127 result = g_variant_type_new_maybe (element);
128 g_variant_type_free (element);
131 g_assert (g_variant_type_is_maybe (result));
132 break;
134 case 2:
135 result = append_tuple_type_string (string, description,
136 definite, depth);
138 g_assert (g_variant_type_is_tuple (result));
139 break;
141 case 3:
143 GVariantType *key, *value;
145 g_string_append_c (string, '{');
146 g_string_append (description, "e of [");
147 key = append_type_string (string, description, definite, 0);
148 g_string_append (description, ", ");
149 value = append_type_string (string, description, definite, depth);
150 g_string_append_c (description, ']');
151 g_string_append_c (string, '}');
152 result = g_variant_type_new_dict_entry (key, value);
153 g_variant_type_free (key);
154 g_variant_type_free (value);
157 g_assert (g_variant_type_is_dict_entry (result));
158 break;
160 case 4:
161 g_string_append_c (string, 'v');
162 g_string_append_c (description, 'V');
163 result = g_variant_type_copy (G_VARIANT_TYPE_VARIANT);
164 g_assert (g_variant_type_equal (result, G_VARIANT_TYPE_VARIANT));
165 break;
167 case 5:
168 g_string_append_c (string, '*');
169 g_string_append_c (description, 'S');
170 result = g_variant_type_copy (G_VARIANT_TYPE_ANY);
171 g_assert (g_variant_type_equal (result, G_VARIANT_TYPE_ANY));
172 break;
174 case 6:
175 g_string_append_c (string, 'r');
176 g_string_append_c (description, 'R');
177 result = g_variant_type_copy (G_VARIANT_TYPE_TUPLE);
178 g_assert (g_variant_type_is_tuple (result));
179 break;
181 default:
182 g_assert_not_reached ();
185 return result;
189 static GVariantType *
190 append_tuple_type_string (GString *string,
191 GString *description,
192 gboolean definite,
193 gint depth)
195 GVariantType *result, *other_result;
196 GVariantType **types;
197 gint size;
198 gint i;
200 g_string_append_c (string, '(');
201 g_string_append (description, "t of [");
203 size = g_test_rand_int_range (0, 20);
204 types = g_new (GVariantType *, size + 1);
206 for (i = 0; i < size; i++)
208 types[i] = append_type_string (string, description, definite, depth);
210 if (i < size - 1)
211 g_string_append (description, ", ");
214 types[i] = NULL;
216 g_string_append_c (description, ']');
217 g_string_append_c (string, ')');
219 result = g_variant_type_new_tuple ((gpointer) types, size);
220 other_result = g_variant_type_new_tuple ((gpointer) types, -1);
221 g_assert (g_variant_type_equal (result, other_result));
222 g_variant_type_free (other_result);
223 for (i = 0; i < size; i++)
224 g_variant_type_free (types[i]);
225 g_free (types);
227 return result;
230 /* given a valid type string, make it invalid */
231 static gchar *
232 invalid_mutation (const gchar *type_string)
234 gboolean have_parens, have_braces;
236 /* it's valid, so '(' implies ')' and same for '{' and '}' */
237 have_parens = strchr (type_string, '(') != NULL;
238 have_braces = strchr (type_string, '{') != NULL;
240 if (have_parens && have_braces && randomly (0.3))
242 /* swap a paren and a brace */
243 gchar *pp, *bp;
244 gint np, nb;
245 gchar p, b;
246 gchar *new;
248 new = g_strdup (type_string);
250 if (randomly (0.5))
251 p = '(', b = '{';
252 else
253 p = ')', b = '}';
255 np = nb = 0;
256 pp = bp = new - 1;
258 /* count number of parens/braces */
259 while ((pp = strchr (pp + 1, p))) np++;
260 while ((bp = strchr (bp + 1, b))) nb++;
262 /* randomly pick one of each */
263 np = g_test_rand_int_range (0, np) + 1;
264 nb = g_test_rand_int_range (0, nb) + 1;
266 /* find it */
267 pp = bp = new - 1;
268 while (np--) pp = strchr (pp + 1, p);
269 while (nb--) bp = strchr (bp + 1, b);
271 /* swap */
272 g_assert (*bp == b && *pp == p);
273 *bp = p;
274 *pp = b;
276 return new;
279 if ((have_parens || have_braces) && randomly (0.3))
281 /* drop a paren/brace */
282 gchar *new;
283 gchar *pp;
284 gint np;
285 gchar p;
287 if (have_parens)
288 if (randomly (0.5)) p = '('; else p = ')';
289 else
290 if (randomly (0.5)) p = '{'; else p = '}';
292 new = g_strdup (type_string);
294 np = 0;
295 pp = new - 1;
296 while ((pp = strchr (pp + 1, p))) np++;
297 np = g_test_rand_int_range (0, np) + 1;
298 pp = new - 1;
299 while (np--) pp = strchr (pp + 1, p);
300 g_assert (*pp == p);
302 while (*pp)
304 *pp = *(pp + 1);
305 pp++;
308 return new;
311 /* else, perform a random mutation at a random point */
313 gint length, n;
314 gchar *new;
315 gchar p;
317 if (randomly (0.3))
319 /* insert a paren/brace */
320 if (randomly (0.5))
321 if (randomly (0.5)) p = '('; else p = ')';
322 else
323 if (randomly (0.5)) p = '{'; else p = '}';
325 else if (randomly (0.5))
327 /* insert junk */
328 p = INVALIDS[g_test_rand_int_range (0, N_INVALIDS)];
330 else
332 /* truncate */
333 p = '\0';
337 length = strlen (type_string);
338 new = g_malloc (length + 2);
339 n = g_test_rand_int_range (0, length);
340 memcpy (new, type_string, n);
341 new[n] = p;
342 memcpy (new + n + 1, type_string + n, length - n);
343 new[length + 1] = '\0';
345 return new;
349 /* describe a type using the same language as is generated
350 * while generating the type with append_type_string
352 static gchar *
353 describe_type (const GVariantType *type)
355 gchar *result;
357 if (g_variant_type_is_container (type))
359 g_assert (!g_variant_type_is_basic (type));
361 if (g_variant_type_is_array (type))
363 gchar *subtype = describe_type (g_variant_type_element (type));
364 result = g_strdup_printf ("a of %s", subtype);
365 g_free (subtype);
367 else if (g_variant_type_is_maybe (type))
369 gchar *subtype = describe_type (g_variant_type_element (type));
370 result = g_strdup_printf ("m of %s", subtype);
371 g_free (subtype);
373 else if (g_variant_type_is_tuple (type))
375 if (!g_variant_type_equal (type, G_VARIANT_TYPE_TUPLE))
377 const GVariantType *sub;
378 GString *string;
379 gint length;
380 gint i;
382 string = g_string_new ("t of [");
384 length = g_variant_type_n_items (type);
385 sub = g_variant_type_first (type);
386 for (i = 0; i < length; i++)
388 gchar *subtype = describe_type (sub);
389 g_string_append (string, subtype);
390 g_free (subtype);
392 if ((sub = g_variant_type_next (sub)))
393 g_string_append (string, ", ");
395 g_assert (sub == NULL);
396 g_string_append_c (string, ']');
398 result = g_string_free (string, FALSE);
400 else
401 result = g_strdup ("R");
403 else if (g_variant_type_is_dict_entry (type))
405 gchar *key, *value, *key2, *value2;
407 key = describe_type (g_variant_type_key (type));
408 value = describe_type (g_variant_type_value (type));
409 key2 = describe_type (g_variant_type_first (type));
410 value2 = describe_type (
411 g_variant_type_next (g_variant_type_first (type)));
412 g_assert (g_variant_type_next (g_variant_type_next (
413 g_variant_type_first (type))) == NULL);
414 g_assert_cmpstr (key, ==, key2);
415 g_assert_cmpstr (value, ==, value2);
416 result = g_strjoin ("", "e of [", key, ", ", value, "]", NULL);
417 g_free (key2);
418 g_free (value2);
419 g_free (key);
420 g_free (value);
422 else if (g_variant_type_equal (type, G_VARIANT_TYPE_VARIANT))
424 result = g_strdup ("V");
426 else
427 g_assert_not_reached ();
429 else
431 if (g_variant_type_is_definite (type))
433 g_assert (g_variant_type_is_basic (type));
435 if (g_variant_type_equal (type, G_VARIANT_TYPE_BOOLEAN))
436 result = g_strdup ("b");
437 else if (g_variant_type_equal (type, G_VARIANT_TYPE_BYTE))
438 result = g_strdup ("y");
439 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT16))
440 result = g_strdup ("n");
441 else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT16))
442 result = g_strdup ("q");
443 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32))
444 result = g_strdup ("i");
445 else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT32))
446 result = g_strdup ("u");
447 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT64))
448 result = g_strdup ("x");
449 else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT64))
450 result = g_strdup ("t");
451 else if (g_variant_type_equal (type, G_VARIANT_TYPE_HANDLE))
452 result = g_strdup ("h");
453 else if (g_variant_type_equal (type, G_VARIANT_TYPE_DOUBLE))
454 result = g_strdup ("d");
455 else if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING))
456 result = g_strdup ("s");
457 else if (g_variant_type_equal (type, G_VARIANT_TYPE_OBJECT_PATH))
458 result = g_strdup ("o");
459 else if (g_variant_type_equal (type, G_VARIANT_TYPE_SIGNATURE))
460 result = g_strdup ("g");
461 else
462 g_assert_not_reached ();
464 else
466 if (g_variant_type_equal (type, G_VARIANT_TYPE_ANY))
468 result = g_strdup ("S");
470 else if (g_variant_type_equal (type, G_VARIANT_TYPE_BASIC))
472 result = g_strdup ("?");
474 else
475 g_assert_not_reached ();
479 return result;
482 /* given a type string, replace one of the indefinite type characters in
483 * it with a matching type (possibly the same type).
485 static gchar *
486 generate_subtype (const gchar *type_string)
488 GVariantType *replacement;
489 GString *result, *junk;
490 gint length, n = 0, l;
492 result = g_string_new (NULL);
493 junk = g_string_new (NULL);
495 /* count the number of indefinite type characters */
496 for (length = 0; type_string[length]; length++)
497 n += type_string[length] == 'r' ||
498 type_string[length] == '?' ||
499 type_string[length] == '*';
500 /* length now is strlen (type_string) */
502 /* pick one at random to replace */
503 n = g_test_rand_int_range (0, n) + 1;
505 /* find it */
506 l = -1;
507 while (n--) l += strcspn (type_string + l + 1, "r?*") + 1;
508 g_assert (type_string[l] == 'r' ||
509 type_string[l] == '?' ||
510 type_string[l] == '*');
512 /* store up to that point in a GString */
513 g_string_append_len (result, type_string, l);
515 /* then store the replacement in the GString */
516 if (type_string[l] == 'r')
517 replacement = append_tuple_type_string (result, junk, FALSE, 3);
519 else if (type_string[l] == '?')
520 replacement = append_type_string (result, junk, FALSE, 0);
522 else if (type_string[l] == '*')
523 replacement = append_type_string (result, junk, FALSE, 3);
525 else
526 g_assert_not_reached ();
528 /* ensure the replacement has the proper type */
529 g_assert (g_variant_type_is_subtype_of (replacement,
530 (gpointer) &type_string[l]));
532 /* store the rest from the original type string */
533 g_string_append (result, type_string + l + 1);
535 g_variant_type_free (replacement);
536 g_string_free (junk, TRUE);
538 return g_string_free (result, FALSE);
541 struct typestack
543 const GVariantType *type;
544 struct typestack *parent;
547 /* given an indefinite type string, replace one of the indefinite
548 * characters in it with a matching type and ensure that the result is a
549 * subtype of the original. repeat.
551 static void
552 subtype_check (const gchar *type_string,
553 struct typestack *parent_ts)
555 struct typestack ts, *node;
556 gchar *subtype;
557 gint depth = 0;
559 subtype = generate_subtype (type_string);
561 ts.type = G_VARIANT_TYPE (subtype);
562 ts.parent = parent_ts;
564 for (node = &ts; node; node = node->parent)
566 /* this type should be a subtype of each parent type */
567 g_assert (g_variant_type_is_subtype_of (ts.type, node->type));
569 /* it should only be a supertype when it is exactly equal */
570 g_assert (g_variant_type_is_subtype_of (node->type, ts.type) ==
571 g_variant_type_equal (ts.type, node->type));
573 depth++;
576 if (!g_variant_type_is_definite (ts.type) && depth < 5)
578 /* the type is still indefinite and we haven't repeated too many
579 * times. go once more.
582 subtype_check (subtype, &ts);
585 g_free (subtype);
588 static void
589 test_gvarianttype (void)
591 gint i;
593 for (i = 0; i < 2000; i++)
595 GString *type_string, *description;
596 GVariantType *type, *other_type;
597 const GVariantType *ctype;
598 gchar *invalid;
599 gchar *desc;
601 type_string = g_string_new (NULL);
602 description = g_string_new (NULL);
604 /* generate a random type, its type string and a description
606 * exercises type constructor functions and g_variant_type_copy()
608 type = append_type_string (type_string, description, FALSE, 6);
610 /* convert the type string to a type and ensure that it is equal
611 * to the one produced with the type constructor routines
613 ctype = G_VARIANT_TYPE (type_string->str);
614 g_assert (g_variant_type_equal (ctype, type));
615 g_assert (g_variant_type_hash (ctype) == g_variant_type_hash (type));
616 g_assert (g_variant_type_is_subtype_of (ctype, type));
617 g_assert (g_variant_type_is_subtype_of (type, ctype));
619 /* check if the type is indefinite */
620 if (!g_variant_type_is_definite (type))
622 struct typestack ts = { type, NULL };
624 /* if it is indefinite, then replace one of the indefinite
625 * characters with a matching type and ensure that the result
626 * is a subtype of the original type. repeat.
628 subtype_check (type_string->str, &ts);
630 else
631 /* ensure that no indefinite characters appear */
632 g_assert (strcspn (type_string->str, "r?*") == type_string->len);
635 /* describe the type.
637 * exercises the type iterator interface
639 desc = describe_type (type);
641 /* make sure the description matches */
642 g_assert_cmpstr (desc, ==, description->str);
643 g_free (desc);
645 /* make an invalid mutation to the type and make sure the type
646 * validation routines catch it */
647 invalid = invalid_mutation (type_string->str);
648 g_assert (g_variant_type_string_is_valid (type_string->str));
649 g_assert (!g_variant_type_string_is_valid (invalid));
650 g_free (invalid);
652 /* concatenate another type to the type string and ensure that
653 * the result is recognised as being invalid
655 other_type = append_type_string (type_string, description, FALSE, 2);
657 g_string_free (description, TRUE);
658 g_string_free (type_string, TRUE);
659 g_variant_type_free (other_type);
660 g_variant_type_free (type);
664 #define ALIGNED(x, y) (((x + (y - 1)) / y) * y)
666 /* do our own calculation of the fixed_size and alignment of a type
667 * using a simple algorithm to make sure the "fancy" one in the
668 * implementation is correct.
670 static void
671 calculate_type_info (const GVariantType *type,
672 gsize *fixed_size,
673 guint *alignment)
675 if (g_variant_type_is_array (type) ||
676 g_variant_type_is_maybe (type))
678 calculate_type_info (g_variant_type_element (type), NULL, alignment);
680 if (fixed_size)
681 *fixed_size = 0;
683 else if (g_variant_type_is_tuple (type) ||
684 g_variant_type_is_dict_entry (type))
686 if (g_variant_type_n_items (type))
688 const GVariantType *sub;
689 gboolean variable;
690 gsize size;
691 guint al;
693 variable = FALSE;
694 size = 0;
695 al = 0;
697 sub = g_variant_type_first (type);
700 gsize this_fs;
701 guint this_al;
703 calculate_type_info (sub, &this_fs, &this_al);
705 al = MAX (al, this_al);
707 if (!this_fs)
709 variable = TRUE;
710 size = 0;
713 if (!variable)
715 size = ALIGNED (size, this_al);
716 size += this_fs;
719 while ((sub = g_variant_type_next (sub)));
721 size = ALIGNED (size, al);
723 if (alignment)
724 *alignment = al;
726 if (fixed_size)
727 *fixed_size = size;
729 else
731 if (fixed_size)
732 *fixed_size = 1;
734 if (alignment)
735 *alignment = 1;
738 else
740 gint fs, al;
742 if (g_variant_type_equal (type, G_VARIANT_TYPE_BOOLEAN) ||
743 g_variant_type_equal (type, G_VARIANT_TYPE_BYTE))
745 al = fs = 1;
748 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT16) ||
749 g_variant_type_equal (type, G_VARIANT_TYPE_UINT16))
751 al = fs = 2;
754 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32) ||
755 g_variant_type_equal (type, G_VARIANT_TYPE_UINT32) ||
756 g_variant_type_equal (type, G_VARIANT_TYPE_HANDLE))
758 al = fs = 4;
761 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT64) ||
762 g_variant_type_equal (type, G_VARIANT_TYPE_UINT64) ||
763 g_variant_type_equal (type, G_VARIANT_TYPE_DOUBLE))
765 al = fs = 8;
767 else if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING) ||
768 g_variant_type_equal (type, G_VARIANT_TYPE_OBJECT_PATH) ||
769 g_variant_type_equal (type, G_VARIANT_TYPE_SIGNATURE))
771 al = 1;
772 fs = 0;
774 else if (g_variant_type_equal (type, G_VARIANT_TYPE_VARIANT))
776 al = 8;
777 fs = 0;
779 else
780 g_assert_not_reached ();
782 if (fixed_size)
783 *fixed_size = fs;
785 if (alignment)
786 *alignment = al;
790 /* same as the describe_type() function above, but iterates over
791 * typeinfo instead of types.
793 static gchar *
794 describe_info (GVariantTypeInfo *info)
796 gchar *result;
798 switch (g_variant_type_info_get_type_char (info))
800 case G_VARIANT_TYPE_INFO_CHAR_MAYBE:
802 gchar *element;
804 element = describe_info (g_variant_type_info_element (info));
805 result = g_strdup_printf ("m of %s", element);
806 g_free (element);
808 break;
810 case G_VARIANT_TYPE_INFO_CHAR_ARRAY:
812 gchar *element;
814 element = describe_info (g_variant_type_info_element (info));
815 result = g_strdup_printf ("a of %s", element);
816 g_free (element);
818 break;
820 case G_VARIANT_TYPE_INFO_CHAR_TUPLE:
822 const gchar *sep = "";
823 GString *string;
824 gint length;
825 gint i;
827 string = g_string_new ("t of [");
828 length = g_variant_type_info_n_members (info);
830 for (i = 0; i < length; i++)
832 const GVariantMemberInfo *minfo;
833 gchar *subtype;
835 g_string_append (string, sep);
836 sep = ", ";
838 minfo = g_variant_type_info_member_info (info, i);
839 subtype = describe_info (minfo->type_info);
840 g_string_append (string, subtype);
841 g_free (subtype);
844 g_string_append_c (string, ']');
846 result = g_string_free (string, FALSE);
848 break;
850 case G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY:
852 const GVariantMemberInfo *keyinfo, *valueinfo;
853 gchar *key, *value;
855 g_assert_cmpint (g_variant_type_info_n_members (info), ==, 2);
856 keyinfo = g_variant_type_info_member_info (info, 0);
857 valueinfo = g_variant_type_info_member_info (info, 1);
858 key = describe_info (keyinfo->type_info);
859 value = describe_info (valueinfo->type_info);
860 result = g_strjoin ("", "e of [", key, ", ", value, "]", NULL);
861 g_free (key);
862 g_free (value);
864 break;
866 case G_VARIANT_TYPE_INFO_CHAR_VARIANT:
867 result = g_strdup ("V");
868 break;
870 default:
871 result = g_strdup (g_variant_type_info_get_type_string (info));
872 g_assert_cmpint (strlen (result), ==, 1);
873 break;
876 return result;
879 /* check that the O(1) method of calculating offsets meshes with the
880 * results of simple iteration.
882 static void
883 check_offsets (GVariantTypeInfo *info,
884 const GVariantType *type)
886 gint flavour;
887 gint length;
889 length = g_variant_type_info_n_members (info);
890 g_assert_cmpint (length, ==, g_variant_type_n_items (type));
892 /* the 'flavour' is the low order bits of the ending point of
893 * variable-size items in the tuple. this lets us test that the type
894 * info is correct for various starting alignments.
896 for (flavour = 0; flavour < 8; flavour++)
898 const GVariantType *subtype;
899 gsize last_offset_index;
900 gsize last_offset;
901 gsize position;
902 gint i;
904 subtype = g_variant_type_first (type);
905 last_offset_index = -1;
906 last_offset = 0;
907 position = 0;
909 /* go through the tuple, keeping track of our position */
910 for (i = 0; i < length; i++)
912 gsize fixed_size;
913 guint alignment;
915 calculate_type_info (subtype, &fixed_size, &alignment);
917 position = ALIGNED (position, alignment);
919 /* compare our current aligned position (ie: the start of this
920 * item) to the start offset that would be calculated if we
921 * used the type info
924 const GVariantMemberInfo *member;
925 gsize start;
927 member = g_variant_type_info_member_info (info, i);
928 g_assert_cmpint (member->i, ==, last_offset_index);
930 /* do the calculation using the typeinfo */
931 start = last_offset;
932 start += member->a;
933 start &= member->b;
934 start |= member->c;
936 /* did we reach the same spot? */
937 g_assert_cmpint (start, ==, position);
940 if (fixed_size)
942 /* fixed size. add that size. */
943 position += fixed_size;
945 else
947 /* variable size. do the flavouring. */
948 while ((position & 0x7) != flavour)
949 position++;
951 /* and store the offset, just like it would be in the
952 * serialised data.
954 last_offset = position;
955 last_offset_index++;
958 /* next type */
959 subtype = g_variant_type_next (subtype);
962 /* make sure we used up exactly all the types */
963 g_assert (subtype == NULL);
967 static void
968 test_gvarianttypeinfo (void)
970 gint i;
972 for (i = 0; i < 2000; i++)
974 GString *type_string, *description;
975 gsize fixed_size1, fixed_size2;
976 guint alignment1, alignment2;
977 GVariantTypeInfo *info;
978 GVariantType *type;
979 gchar *desc;
981 type_string = g_string_new (NULL);
982 description = g_string_new (NULL);
984 /* random type */
985 type = append_type_string (type_string, description, TRUE, 6);
987 /* create a typeinfo for it */
988 info = g_variant_type_info_get (type);
990 /* make sure the typeinfo has the right type string */
991 g_assert_cmpstr (g_variant_type_info_get_type_string (info), ==,
992 type_string->str);
994 /* calculate the alignment and fixed size, compare to the
995 * typeinfo's calculations
997 calculate_type_info (type, &fixed_size1, &alignment1);
998 g_variant_type_info_query (info, &alignment2, &fixed_size2);
999 g_assert_cmpint (fixed_size1, ==, fixed_size2);
1000 g_assert_cmpint (alignment1, ==, alignment2 + 1);
1002 /* test the iteration functions over typeinfo structures by
1003 * "describing" the typeinfo and verifying equality.
1005 desc = describe_info (info);
1006 g_assert_cmpstr (desc, ==, description->str);
1008 /* do extra checks for containers */
1009 if (g_variant_type_is_array (type) ||
1010 g_variant_type_is_maybe (type))
1012 const GVariantType *element;
1013 gsize efs1, efs2;
1014 guint ea1, ea2;
1016 element = g_variant_type_element (type);
1017 calculate_type_info (element, &efs1, &ea1);
1018 g_variant_type_info_query_element (info, &ea2, &efs2);
1019 g_assert_cmpint (efs1, ==, efs2);
1020 g_assert_cmpint (ea1, ==, ea2 + 1);
1022 g_assert_cmpint (ea1, ==, alignment1);
1023 g_assert_cmpint (0, ==, fixed_size1);
1025 else if (g_variant_type_is_tuple (type) ||
1026 g_variant_type_is_dict_entry (type))
1028 /* make sure the "magic constants" are working */
1029 check_offsets (info, type);
1032 g_string_free (type_string, TRUE);
1033 g_string_free (description, TRUE);
1034 g_variant_type_info_unref (info);
1035 g_variant_type_free (type);
1036 g_free (desc);
1039 g_variant_type_info_assert_no_infos ();
1042 #define MAX_FIXED_MULTIPLIER 256
1043 #define MAX_INSTANCE_SIZE 1024
1044 #define MAX_ARRAY_CHILDREN 128
1045 #define MAX_TUPLE_CHILDREN 128
1047 /* this function generates a random type such that all characteristics
1048 * that are "interesting" to the serialiser are tested.
1050 * this basically means:
1051 * - test different alignments
1052 * - test variable sized items and fixed sized items
1053 * - test different fixed sizes
1055 static gchar *
1056 random_type_string (void)
1058 const guchar base_types[] = "ynix";
1059 guchar base_type;
1061 base_type = base_types[g_test_rand_int_range (0, 4)];
1063 if (g_test_rand_bit ())
1064 /* construct a fixed-sized type */
1066 char type_string[MAX_FIXED_MULTIPLIER];
1067 guint multiplier;
1068 guint i = 0;
1070 multiplier = g_test_rand_int_range (1, sizeof type_string - 1);
1072 type_string[i++] = '(';
1073 while (multiplier--)
1074 type_string[i++] = base_type;
1075 type_string[i++] = ')';
1077 return g_strndup (type_string, i);
1079 else
1080 /* construct a variable-sized type */
1082 char type_string[2] = { 'a', base_type };
1084 return g_strndup (type_string, 2);
1088 typedef struct
1090 GVariantTypeInfo *type_info;
1091 guint alignment;
1092 gsize size;
1093 gboolean is_fixed_sized;
1095 guint32 seed;
1097 #define INSTANCE_MAGIC 1287582829
1098 guint magic;
1099 } RandomInstance;
1101 static RandomInstance *
1102 random_instance (GVariantTypeInfo *type_info)
1104 RandomInstance *instance;
1106 instance = g_slice_new (RandomInstance);
1108 if (type_info == NULL)
1110 gchar *str = random_type_string ();
1111 instance->type_info = g_variant_type_info_get (G_VARIANT_TYPE (str));
1112 g_free (str);
1114 else
1115 instance->type_info = g_variant_type_info_ref (type_info);
1117 instance->seed = g_test_rand_int ();
1119 g_variant_type_info_query (instance->type_info,
1120 &instance->alignment,
1121 &instance->size);
1123 instance->is_fixed_sized = instance->size != 0;
1125 if (!instance->is_fixed_sized)
1126 instance->size = g_test_rand_int_range (0, MAX_INSTANCE_SIZE);
1128 instance->magic = INSTANCE_MAGIC;
1130 return instance;
1133 static void
1134 random_instance_free (RandomInstance *instance)
1136 g_variant_type_info_unref (instance->type_info);
1137 g_slice_free (RandomInstance, instance);
1140 static void
1141 append_instance_size (RandomInstance *instance,
1142 gsize *offset)
1144 *offset += (-*offset) & instance->alignment;
1145 *offset += instance->size;
1148 static void
1149 random_instance_write (RandomInstance *instance,
1150 guchar *buffer)
1152 GRand *rand;
1153 gint i;
1155 g_assert_cmpint ((gsize) buffer & ALIGN_BITS & instance->alignment, ==, 0);
1157 rand = g_rand_new_with_seed (instance->seed);
1158 for (i = 0; i < instance->size; i++)
1159 buffer[i] = g_rand_int (rand);
1160 g_rand_free (rand);
1163 static void
1164 append_instance_data (RandomInstance *instance,
1165 guchar **buffer)
1167 while (((gsize) *buffer) & instance->alignment)
1168 *(*buffer)++ = '\0';
1170 random_instance_write (instance, *buffer);
1171 *buffer += instance->size;
1174 static gboolean
1175 random_instance_assert (RandomInstance *instance,
1176 guchar *buffer,
1177 gsize size)
1179 GRand *rand;
1180 gint i;
1182 g_assert_cmpint ((gsize) buffer & ALIGN_BITS & instance->alignment, ==, 0);
1183 g_assert_cmpint (size, ==, instance->size);
1185 rand = g_rand_new_with_seed (instance->seed);
1186 for (i = 0; i < instance->size; i++)
1188 guchar byte = g_rand_int (rand);
1190 g_assert (buffer[i] == byte);
1192 g_rand_free (rand);
1194 return i == instance->size;
1197 static gboolean
1198 random_instance_check (RandomInstance *instance,
1199 guchar *buffer,
1200 gsize size)
1202 GRand *rand;
1203 gint i;
1205 g_assert_cmpint ((gsize) buffer & ALIGN_BITS & instance->alignment, ==, 0);
1207 if (size != instance->size)
1208 return FALSE;
1210 rand = g_rand_new_with_seed (instance->seed);
1211 for (i = 0; i < instance->size; i++)
1212 if (buffer[i] != (guchar) g_rand_int (rand))
1213 break;
1214 g_rand_free (rand);
1216 return i == instance->size;
1219 static void
1220 random_instance_filler (GVariantSerialised *serialised,
1221 gpointer data)
1223 RandomInstance *instance = data;
1225 g_assert (instance->magic == INSTANCE_MAGIC);
1227 if (serialised->type_info == NULL)
1228 serialised->type_info = instance->type_info;
1230 if (serialised->size == 0)
1231 serialised->size = instance->size;
1233 g_assert (serialised->type_info == instance->type_info);
1234 g_assert (serialised->size == instance->size);
1236 if (serialised->data)
1237 random_instance_write (instance, serialised->data);
1240 static gsize
1241 calculate_offset_size (gsize body_size,
1242 gsize n_offsets)
1244 if (body_size == 0)
1245 return 0;
1247 if (body_size + n_offsets <= G_MAXUINT8)
1248 return 1;
1250 if (body_size + 2 * n_offsets <= G_MAXUINT16)
1251 return 2;
1253 if (body_size + 4 * n_offsets <= G_MAXUINT32)
1254 return 4;
1256 /* the test case won't generate anything bigger */
1257 g_assert_not_reached ();
1260 static gpointer
1261 flavoured_malloc (gsize size, gsize flavour)
1263 g_assert (flavour < 8);
1265 if (size == 0)
1266 return NULL;
1268 return ((gchar *) g_malloc (size + flavour)) + flavour;
1271 static void
1272 flavoured_free (gpointer data,
1273 gsize flavour)
1275 if (!data)
1276 return;
1277 g_free (((gchar *) data) - flavour);
1280 static gpointer
1281 align_malloc (gsize size)
1283 gpointer mem;
1285 #ifdef HAVE_POSIX_MEMALIGN
1286 if (posix_memalign (&mem, 8, size))
1287 g_error ("posix_memalign failed");
1288 #else
1289 /* NOTE: there may be platforms that lack posix_memalign() and also
1290 * have malloc() that returns non-8-aligned. if so, we need to try
1291 * harder here.
1293 mem = malloc (size);
1294 #endif
1296 return mem;
1299 static void
1300 align_free (gpointer mem)
1302 free (mem);
1305 static void
1306 append_offset (guchar **offset_ptr,
1307 gsize offset,
1308 guint offset_size)
1310 union
1312 guchar bytes[sizeof (gsize)];
1313 gsize integer;
1314 } tmpvalue;
1316 tmpvalue.integer = GSIZE_TO_LE (offset);
1317 memcpy (*offset_ptr, tmpvalue.bytes, offset_size);
1318 *offset_ptr += offset_size;
1321 static void
1322 prepend_offset (guchar **offset_ptr,
1323 gsize offset,
1324 guint offset_size)
1326 union
1328 guchar bytes[sizeof (gsize)];
1329 gsize integer;
1330 } tmpvalue;
1332 *offset_ptr -= offset_size;
1333 tmpvalue.integer = GSIZE_TO_LE (offset);
1334 memcpy (*offset_ptr, tmpvalue.bytes, offset_size);
1337 static void
1338 test_maybe (void)
1340 GVariantTypeInfo *type_info;
1341 RandomInstance *instance;
1342 gsize needed_size;
1343 guchar *data;
1345 instance = random_instance (NULL);
1348 const gchar *element;
1349 gchar *tmp;
1351 element = g_variant_type_info_get_type_string (instance->type_info);
1352 tmp = g_strdup_printf ("m%s", element);
1353 type_info = g_variant_type_info_get (G_VARIANT_TYPE (tmp));
1354 g_free (tmp);
1357 needed_size = g_variant_serialiser_needed_size (type_info,
1358 random_instance_filler,
1359 NULL, 0);
1360 g_assert_cmpint (needed_size, ==, 0);
1362 needed_size = g_variant_serialiser_needed_size (type_info,
1363 random_instance_filler,
1364 (gpointer *) &instance, 1);
1366 if (instance->is_fixed_sized)
1367 g_assert_cmpint (needed_size, ==, instance->size);
1368 else
1369 g_assert_cmpint (needed_size, ==, instance->size + 1);
1372 guchar *ptr;
1374 ptr = data = align_malloc (needed_size);
1375 append_instance_data (instance, &ptr);
1377 if (!instance->is_fixed_sized)
1378 *ptr++ = '\0';
1380 g_assert_cmpint (ptr - data, ==, needed_size);
1384 guint alignment;
1385 guint flavour;
1387 alignment = (instance->alignment & ALIGN_BITS) + 1;
1389 for (flavour = 0; flavour < 8; flavour += alignment)
1391 GVariantSerialised serialised;
1392 GVariantSerialised child;
1394 serialised.type_info = type_info;
1395 serialised.data = flavoured_malloc (needed_size, flavour);
1396 serialised.size = needed_size;
1398 g_variant_serialiser_serialise (serialised,
1399 random_instance_filler,
1400 (gpointer *) &instance, 1);
1401 child = g_variant_serialised_get_child (serialised, 0);
1402 g_assert (child.type_info == instance->type_info);
1403 random_instance_assert (instance, child.data, child.size);
1404 g_variant_type_info_unref (child.type_info);
1405 flavoured_free (serialised.data, flavour);
1409 g_variant_type_info_unref (type_info);
1410 random_instance_free (instance);
1411 align_free (data);
1414 static void
1415 test_maybes (void)
1417 guint i;
1419 for (i = 0; i < 1000; i++)
1420 test_maybe ();
1422 g_variant_type_info_assert_no_infos ();
1425 static void
1426 test_array (void)
1428 GVariantTypeInfo *element_info;
1429 GVariantTypeInfo *array_info;
1430 RandomInstance **instances;
1431 gsize needed_size;
1432 gsize offset_size;
1433 guint n_children;
1434 guchar *data;
1437 gchar *element_type, *array_type;
1439 element_type = random_type_string ();
1440 array_type = g_strdup_printf ("a%s", element_type);
1442 element_info = g_variant_type_info_get (G_VARIANT_TYPE (element_type));
1443 array_info = g_variant_type_info_get (G_VARIANT_TYPE (array_type));
1444 g_assert (g_variant_type_info_element (array_info) == element_info);
1446 g_free (element_type);
1447 g_free (array_type);
1451 guint i;
1453 n_children = g_test_rand_int_range (0, MAX_ARRAY_CHILDREN);
1454 instances = g_new (RandomInstance *, n_children);
1455 for (i = 0; i < n_children; i++)
1456 instances[i] = random_instance (element_info);
1459 needed_size = g_variant_serialiser_needed_size (array_info,
1460 random_instance_filler,
1461 (gpointer *) instances,
1462 n_children);
1465 gsize element_fixed_size;
1466 gsize body_size = 0;
1467 guint i;
1469 for (i = 0; i < n_children; i++)
1470 append_instance_size (instances[i], &body_size);
1472 g_variant_type_info_query (element_info, NULL, &element_fixed_size);
1474 if (!element_fixed_size)
1476 offset_size = calculate_offset_size (body_size, n_children);
1478 if (offset_size == 0)
1479 offset_size = 1;
1481 else
1482 offset_size = 0;
1484 g_assert_cmpint (needed_size, ==, body_size + n_children * offset_size);
1488 guchar *offset_ptr, *body_ptr;
1489 guint i;
1491 body_ptr = data = align_malloc (needed_size);
1492 offset_ptr = body_ptr + needed_size - offset_size * n_children;
1494 for (i = 0; i < n_children; i++)
1496 append_instance_data (instances[i], &body_ptr);
1497 append_offset (&offset_ptr, body_ptr - data, offset_size);
1500 g_assert (body_ptr == data + needed_size - offset_size * n_children);
1501 g_assert (offset_ptr == data + needed_size);
1505 guint alignment;
1506 gsize flavour;
1507 guint i;
1509 g_variant_type_info_query (array_info, &alignment, NULL);
1510 alignment = (alignment & ALIGN_BITS) + 1;
1512 for (flavour = 0; flavour < 8; flavour += alignment)
1514 GVariantSerialised serialised;
1516 serialised.type_info = array_info;
1517 serialised.data = flavoured_malloc (needed_size, flavour);
1518 serialised.size = needed_size;
1520 g_variant_serialiser_serialise (serialised, random_instance_filler,
1521 (gpointer *) instances, n_children);
1523 if (serialised.size)
1524 g_assert (memcmp (serialised.data, data, serialised.size) == 0);
1526 g_assert (g_variant_serialised_n_children (serialised) == n_children);
1528 for (i = 0; i < n_children; i++)
1530 GVariantSerialised child;
1532 child = g_variant_serialised_get_child (serialised, i);
1533 g_assert (child.type_info == instances[i]->type_info);
1534 random_instance_assert (instances[i], child.data, child.size);
1535 g_variant_type_info_unref (child.type_info);
1538 flavoured_free (serialised.data, flavour);
1543 guint i;
1545 for (i = 0; i < n_children; i++)
1546 random_instance_free (instances[i]);
1547 g_free (instances);
1550 g_variant_type_info_unref (element_info);
1551 g_variant_type_info_unref (array_info);
1552 align_free (data);
1555 static void
1556 test_arrays (void)
1558 guint i;
1560 for (i = 0; i < 100; i++)
1561 test_array ();
1563 g_variant_type_info_assert_no_infos ();
1566 static void
1567 test_tuple (void)
1569 GVariantTypeInfo *type_info;
1570 RandomInstance **instances;
1571 gboolean fixed_size;
1572 gsize needed_size;
1573 gsize offset_size;
1574 guint n_children;
1575 guint alignment;
1576 guchar *data;
1578 n_children = g_test_rand_int_range (0, MAX_TUPLE_CHILDREN);
1579 instances = g_new (RandomInstance *, n_children);
1582 GString *type_string;
1583 guint i;
1585 fixed_size = TRUE;
1586 alignment = 0;
1588 type_string = g_string_new ("(");
1589 for (i = 0; i < n_children; i++)
1591 const gchar *str;
1593 instances[i] = random_instance (NULL);
1595 alignment |= instances[i]->alignment;
1596 if (!instances[i]->is_fixed_sized)
1597 fixed_size = FALSE;
1599 str = g_variant_type_info_get_type_string (instances[i]->type_info);
1600 g_string_append (type_string, str);
1602 g_string_append_c (type_string, ')');
1604 type_info = g_variant_type_info_get (G_VARIANT_TYPE (type_string->str));
1605 g_string_free (type_string, TRUE);
1608 needed_size = g_variant_serialiser_needed_size (type_info,
1609 random_instance_filler,
1610 (gpointer *) instances,
1611 n_children);
1613 gsize body_size = 0;
1614 gsize offsets = 0;
1615 guint i;
1617 for (i = 0; i < n_children; i++)
1619 append_instance_size (instances[i], &body_size);
1621 if (i != n_children - 1 && !instances[i]->is_fixed_sized)
1622 offsets++;
1625 if (fixed_size)
1627 body_size += (-body_size) & alignment;
1629 g_assert ((body_size == 0) == (n_children == 0));
1630 if (n_children == 0)
1631 body_size = 1;
1634 offset_size = calculate_offset_size (body_size, offsets);
1635 g_assert_cmpint (needed_size, ==, body_size + offsets * offset_size);
1639 guchar *body_ptr;
1640 guchar *ofs_ptr;
1641 guint i;
1643 body_ptr = data = align_malloc (needed_size);
1644 ofs_ptr = body_ptr + needed_size;
1646 for (i = 0; i < n_children; i++)
1648 append_instance_data (instances[i], &body_ptr);
1650 if (i != n_children - 1 && !instances[i]->is_fixed_sized)
1651 prepend_offset (&ofs_ptr, body_ptr - data, offset_size);
1654 if (fixed_size)
1656 while (((gsize) body_ptr) & alignment)
1657 *body_ptr++ = '\0';
1659 g_assert ((body_ptr == data) == (n_children == 0));
1660 if (n_children == 0)
1661 *body_ptr++ = '\0';
1666 g_assert (body_ptr == ofs_ptr);
1670 gsize flavour;
1671 guint i;
1673 alignment = (alignment & ALIGN_BITS) + 1;
1675 for (flavour = 0; flavour < 8; flavour += alignment)
1677 GVariantSerialised serialised;
1679 serialised.type_info = type_info;
1680 serialised.data = flavoured_malloc (needed_size, flavour);
1681 serialised.size = needed_size;
1683 g_variant_serialiser_serialise (serialised, random_instance_filler,
1684 (gpointer *) instances, n_children);
1686 if (serialised.size)
1687 g_assert (memcmp (serialised.data, data, serialised.size) == 0);
1689 g_assert (g_variant_serialised_n_children (serialised) == n_children);
1691 for (i = 0; i < n_children; i++)
1693 GVariantSerialised child;
1695 child = g_variant_serialised_get_child (serialised, i);
1696 g_assert (child.type_info == instances[i]->type_info);
1697 random_instance_assert (instances[i], child.data, child.size);
1698 g_variant_type_info_unref (child.type_info);
1701 flavoured_free (serialised.data, flavour);
1706 guint i;
1708 for (i = 0; i < n_children; i++)
1709 random_instance_free (instances[i]);
1710 g_free (instances);
1713 g_variant_type_info_unref (type_info);
1714 align_free (data);
1717 static void
1718 test_tuples (void)
1720 guint i;
1722 for (i = 0; i < 100; i++)
1723 test_tuple ();
1725 g_variant_type_info_assert_no_infos ();
1728 static void
1729 test_variant (void)
1731 GVariantTypeInfo *type_info;
1732 RandomInstance *instance;
1733 const gchar *type_string;
1734 gsize needed_size;
1735 guchar *data;
1736 gsize len;
1738 type_info = g_variant_type_info_get (G_VARIANT_TYPE_VARIANT);
1739 instance = random_instance (NULL);
1741 type_string = g_variant_type_info_get_type_string (instance->type_info);
1742 len = strlen (type_string);
1744 needed_size = g_variant_serialiser_needed_size (type_info,
1745 random_instance_filler,
1746 (gpointer *) &instance, 1);
1748 g_assert_cmpint (needed_size, ==, instance->size + 1 + len);
1751 guchar *ptr;
1753 ptr = data = align_malloc (needed_size);
1754 append_instance_data (instance, &ptr);
1755 *ptr++ = '\0';
1756 memcpy (ptr, type_string, len);
1757 ptr += len;
1759 g_assert (data + needed_size == ptr);
1763 gsize alignment;
1764 gsize flavour;
1766 /* variants are always 8-aligned */
1767 alignment = ALIGN_BITS + 1;
1769 for (flavour = 0; flavour < 8; flavour += alignment)
1771 GVariantSerialised serialised;
1772 GVariantSerialised child;
1774 serialised.type_info = type_info;
1775 serialised.data = flavoured_malloc (needed_size, flavour);
1776 serialised.size = needed_size;
1778 g_variant_serialiser_serialise (serialised, random_instance_filler,
1779 (gpointer *) &instance, 1);
1781 if (serialised.size)
1782 g_assert (memcmp (serialised.data, data, serialised.size) == 0);
1784 g_assert (g_variant_serialised_n_children (serialised) == 1);
1786 child = g_variant_serialised_get_child (serialised, 0);
1787 g_assert (child.type_info == instance->type_info);
1788 random_instance_check (instance, child.data, child.size);
1790 g_variant_type_info_unref (child.type_info);
1791 flavoured_free (serialised.data, flavour);
1795 g_variant_type_info_unref (type_info);
1796 random_instance_free (instance);
1797 align_free (data);
1800 static void
1801 test_variants (void)
1803 guint i;
1805 for (i = 0; i < 100; i++)
1806 test_variant ();
1808 g_variant_type_info_assert_no_infos ();
1811 static void
1812 test_strings (void)
1814 struct {
1815 guint flags;
1816 guint size;
1817 gconstpointer data;
1818 } test_cases[] = {
1819 #define is_nval 0
1820 #define is_string 1
1821 #define is_objpath is_string | 2
1822 #define is_sig is_string | 4
1823 { is_sig, 1, "" },
1824 { is_nval, 0, NULL },
1825 { is_nval, 13, "hello\xffworld!" },
1826 { is_string, 13, "hello world!" },
1827 { is_nval, 13, "hello world\0" },
1828 { is_nval, 13, "hello\0world!" },
1829 { is_nval, 12, "hello world!" },
1830 { is_nval, 13, "hello world!\xff" },
1832 { is_objpath, 2, "/" },
1833 { is_objpath, 3, "/a" },
1834 { is_string, 3, "//" },
1835 { is_objpath, 11, "/some/path" },
1836 { is_string, 12, "/some/path/" },
1837 { is_nval, 11, "/some\0path" },
1838 { is_string, 11, "/some\\path" },
1839 { is_string, 12, "/some//path" },
1840 { is_string, 12, "/some-/path" },
1842 { is_sig, 2, "i" },
1843 { is_sig, 2, "s" },
1844 { is_sig, 5, "(si)" },
1845 { is_string, 4, "(si" },
1846 { is_string, 2, "*" },
1847 { is_sig, 3, "ai" },
1848 { is_string, 3, "mi" },
1849 { is_string, 2, "r" },
1850 { is_sig, 15, "(yyy{sv}ssiai)" },
1851 { is_string, 16, "(yyy{yv}ssiai))" },
1852 { is_string, 15, "(yyy{vv}ssiai)" },
1853 { is_string, 15, "(yyy{sv)ssiai}" }
1855 guint i;
1857 for (i = 0; i < G_N_ELEMENTS (test_cases); i++)
1859 guint flags;
1861 flags = g_variant_serialiser_is_string (test_cases[i].data,
1862 test_cases[i].size)
1863 ? 1 : 0;
1865 flags |= g_variant_serialiser_is_object_path (test_cases[i].data,
1866 test_cases[i].size)
1867 ? 2 : 0;
1869 flags |= g_variant_serialiser_is_signature (test_cases[i].data,
1870 test_cases[i].size)
1871 ? 4 : 0;
1873 g_assert (flags == test_cases[i].flags);
1877 typedef struct _TreeInstance TreeInstance;
1878 struct _TreeInstance
1880 GVariantTypeInfo *info;
1882 TreeInstance **children;
1883 gsize n_children;
1885 union {
1886 guint64 integer;
1887 gdouble floating;
1888 gchar string[200];
1889 } data;
1890 gsize data_size;
1893 static GVariantType *
1894 make_random_definite_type (int depth)
1896 GString *description;
1897 GString *type_string;
1898 GVariantType *type;
1900 description = g_string_new (NULL);
1901 type_string = g_string_new (NULL);
1902 type = append_type_string (type_string, description, TRUE, depth);
1903 g_string_free (description, TRUE);
1904 g_string_free (type_string, TRUE);
1906 return type;
1909 static void
1910 make_random_string (gchar *string,
1911 gsize size,
1912 const GVariantType *type)
1914 gint i;
1916 /* create strings that are valid signature strings */
1917 #define good_chars "bynqiuxthdsog"
1919 for (i = 0; i < size - 1; i++)
1920 string[i] = good_chars[g_test_rand_int_range (0, strlen (good_chars))];
1921 string[i] = '\0';
1923 /* in case we need an object path, prefix a '/' */
1924 if (*g_variant_type_peek_string (type) == 'o')
1925 string[0] = '/';
1927 #undef good_chars
1930 static TreeInstance *
1931 tree_instance_new (const GVariantType *type,
1932 int depth)
1934 const GVariantType *child_type = NULL;
1935 GVariantType *mytype = NULL;
1936 TreeInstance *instance;
1937 gboolean is_tuple_type;
1939 if (type == NULL)
1940 type = mytype = make_random_definite_type (depth);
1942 instance = g_slice_new (TreeInstance);
1943 instance->info = g_variant_type_info_get (type);
1944 instance->children = NULL;
1945 instance->n_children = 0;
1946 instance->data_size = 0;
1948 is_tuple_type = FALSE;
1950 switch (*g_variant_type_peek_string (type))
1952 case G_VARIANT_TYPE_INFO_CHAR_MAYBE:
1953 instance->n_children = g_test_rand_int_range (0, 2);
1954 child_type = g_variant_type_element (type);
1955 break;
1957 case G_VARIANT_TYPE_INFO_CHAR_ARRAY:
1958 instance->n_children = g_test_rand_int_range (0, MAX_ARRAY_CHILDREN);
1959 child_type = g_variant_type_element (type);
1960 break;
1962 case G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY:
1963 case G_VARIANT_TYPE_INFO_CHAR_TUPLE:
1964 instance->n_children = g_variant_type_n_items (type);
1965 child_type = g_variant_type_first (type);
1966 is_tuple_type = TRUE;
1967 break;
1969 case G_VARIANT_TYPE_INFO_CHAR_VARIANT:
1970 instance->n_children = 1;
1971 child_type = NULL;
1972 break;
1974 case 'b':
1975 instance->data.integer = g_test_rand_int_range (0, 2);
1976 instance->data_size = 1;
1977 break;
1979 case 'y':
1980 instance->data.integer = g_test_rand_int ();
1981 instance->data_size = 1;
1982 break;
1984 case 'n': case 'q':
1985 instance->data.integer = g_test_rand_int ();
1986 instance->data_size = 2;
1987 break;
1989 case 'i': case 'u': case 'h':
1990 instance->data.integer = g_test_rand_int ();
1991 instance->data_size = 4;
1992 break;
1994 case 'x': case 't':
1995 instance->data.integer = g_test_rand_int ();
1996 instance->data.integer <<= 32;
1997 instance->data.integer |= (guint32) g_test_rand_int ();
1998 instance->data_size = 8;
1999 break;
2001 case 'd':
2002 instance->data.floating = g_test_rand_double ();
2003 instance->data_size = 8;
2004 break;
2006 case 's': case 'o': case 'g':
2007 instance->data_size = g_test_rand_int_range (10, 200);
2008 make_random_string (instance->data.string, instance->data_size, type);
2009 break;
2012 if (instance->data_size == 0)
2013 /* no data -> it is a container */
2015 guint i;
2017 instance->children = g_new (TreeInstance *, instance->n_children);
2019 for (i = 0; i < instance->n_children; i++)
2021 instance->children[i] = tree_instance_new (child_type, depth - 1);
2023 if (is_tuple_type)
2024 child_type = g_variant_type_next (child_type);
2027 g_assert (!is_tuple_type || child_type == NULL);
2030 g_variant_type_free (mytype);
2032 return instance;
2035 static void
2036 tree_instance_free (TreeInstance *instance)
2038 gint i;
2040 g_variant_type_info_unref (instance->info);
2041 for (i = 0; i < instance->n_children; i++)
2042 tree_instance_free (instance->children[i]);
2043 g_free (instance->children);
2044 g_slice_free (TreeInstance, instance);
2047 static gboolean i_am_writing_byteswapped;
2049 static void
2050 tree_filler (GVariantSerialised *serialised,
2051 gpointer data)
2053 TreeInstance *instance = data;
2055 if (serialised->type_info == NULL)
2056 serialised->type_info = instance->info;
2058 if (instance->data_size == 0)
2059 /* is a container */
2061 if (serialised->size == 0)
2062 serialised->size =
2063 g_variant_serialiser_needed_size (instance->info, tree_filler,
2064 (gpointer *) instance->children,
2065 instance->n_children);
2067 if (serialised->data)
2068 g_variant_serialiser_serialise (*serialised, tree_filler,
2069 (gpointer *) instance->children,
2070 instance->n_children);
2072 else
2073 /* it is a leaf */
2075 if (serialised->size == 0)
2076 serialised->size = instance->data_size;
2078 if (serialised->data)
2080 switch (instance->data_size)
2082 case 1:
2083 *serialised->data = instance->data.integer;
2084 break;
2086 case 2:
2088 guint16 value = instance->data.integer;
2090 if (i_am_writing_byteswapped)
2091 value = GUINT16_SWAP_LE_BE (value);
2093 *(guint16 *) serialised->data = value;
2095 break;
2097 case 4:
2099 guint32 value = instance->data.integer;
2101 if (i_am_writing_byteswapped)
2102 value = GUINT32_SWAP_LE_BE (value);
2104 *(guint32 *) serialised->data = value;
2106 break;
2108 case 8:
2110 guint64 value = instance->data.integer;
2112 if (i_am_writing_byteswapped)
2113 value = GUINT64_SWAP_LE_BE (value);
2115 *(guint64 *) serialised->data = value;
2117 break;
2119 default:
2120 memcpy (serialised->data,
2121 instance->data.string,
2122 instance->data_size);
2123 break;
2129 static gboolean
2130 check_tree (TreeInstance *instance,
2131 GVariantSerialised serialised)
2133 if (instance->info != serialised.type_info)
2134 return FALSE;
2136 if (instance->data_size == 0)
2137 /* is a container */
2139 gint i;
2141 if (g_variant_serialised_n_children (serialised) !=
2142 instance->n_children)
2143 return FALSE;
2145 for (i = 0; i < instance->n_children; i++)
2147 GVariantSerialised child;
2148 gpointer data = NULL;
2149 gboolean ok;
2151 child = g_variant_serialised_get_child (serialised, i);
2152 if (child.size && child.data == NULL)
2153 child.data = data = g_malloc0 (child.size);
2154 ok = check_tree (instance->children[i], child);
2155 g_variant_type_info_unref (child.type_info);
2156 g_free (data);
2158 if (!ok)
2159 return FALSE;
2162 return TRUE;
2164 else
2165 /* it is a leaf */
2167 switch (instance->data_size)
2169 case 1:
2170 g_assert (serialised.size == 1);
2171 return *(guint8 *) serialised.data ==
2172 (guint8) instance->data.integer;
2174 case 2:
2175 g_assert (serialised.size == 2);
2176 return *(guint16 *) serialised.data ==
2177 (guint16) instance->data.integer;
2179 case 4:
2180 g_assert (serialised.size == 4);
2181 return *(guint32 *) serialised.data ==
2182 (guint32) instance->data.integer;
2184 case 8:
2185 g_assert (serialised.size == 8);
2186 return *(guint64 *) serialised.data ==
2187 (guint64) instance->data.integer;
2189 default:
2190 if (serialised.size != instance->data_size)
2191 return FALSE;
2193 return memcmp (serialised.data,
2194 instance->data.string,
2195 instance->data_size) == 0;
2200 static void
2201 serialise_tree (TreeInstance *tree,
2202 GVariantSerialised *serialised)
2204 GVariantSerialised empty = {0, };
2206 *serialised = empty;
2207 tree_filler (serialised, tree);
2208 serialised->data = g_malloc (serialised->size);
2209 tree_filler (serialised, tree);
2212 static void
2213 test_byteswap (void)
2215 GVariantSerialised one, two;
2216 TreeInstance *tree;
2218 tree = tree_instance_new (NULL, 3);
2219 serialise_tree (tree, &one);
2221 i_am_writing_byteswapped = TRUE;
2222 serialise_tree (tree, &two);
2223 i_am_writing_byteswapped = FALSE;
2225 g_variant_serialised_byteswap (two);
2227 g_assert_cmpmem (one.data, one.size, two.data, two.size);
2229 tree_instance_free (tree);
2230 g_free (one.data);
2231 g_free (two.data);
2234 static void
2235 test_byteswaps (void)
2237 int i;
2239 for (i = 0; i < 200; i++)
2240 test_byteswap ();
2242 g_variant_type_info_assert_no_infos ();
2245 static void
2246 test_fuzz (gdouble *fuzziness)
2248 GVariantSerialised serialised;
2249 TreeInstance *tree;
2251 /* make an instance */
2252 tree = tree_instance_new (NULL, 3);
2254 /* serialise it */
2255 serialise_tree (tree, &serialised);
2257 g_assert (g_variant_serialised_is_normal (serialised));
2258 g_assert (check_tree (tree, serialised));
2260 if (serialised.size)
2262 gboolean fuzzed = FALSE;
2263 gboolean a, b;
2265 while (!fuzzed)
2267 gint i;
2269 for (i = 0; i < serialised.size; i++)
2270 if (randomly (*fuzziness))
2272 serialised.data[i] += g_test_rand_int_range (1, 256);
2273 fuzzed = TRUE;
2277 /* at least one byte in the serialised data has changed.
2279 * this means that at least one of the following is true:
2281 * - the serialised data now represents a different value:
2282 * check_tree() will return FALSE
2284 * - the serialised data is in non-normal form:
2285 * g_variant_serialiser_is_normal() will return FALSE
2287 * we always do both checks to increase exposure of the serialiser
2288 * to corrupt data.
2290 a = g_variant_serialised_is_normal (serialised);
2291 b = check_tree (tree, serialised);
2293 g_assert (!a || !b);
2296 tree_instance_free (tree);
2297 g_free (serialised.data);
2301 static void
2302 test_fuzzes (gpointer data)
2304 gdouble fuzziness;
2305 int i;
2307 fuzziness = GPOINTER_TO_INT (data) / 100.;
2309 for (i = 0; i < 200; i++)
2310 test_fuzz (&fuzziness);
2312 g_variant_type_info_assert_no_infos ();
2315 static GVariant *
2316 tree_instance_get_gvariant (TreeInstance *tree)
2318 const GVariantType *type;
2319 GVariant *result;
2321 type = (GVariantType *) g_variant_type_info_get_type_string (tree->info);
2323 switch (g_variant_type_info_get_type_char (tree->info))
2325 case G_VARIANT_TYPE_INFO_CHAR_MAYBE:
2327 const GVariantType *child_type;
2328 GVariant *child;
2330 if (tree->n_children)
2331 child = tree_instance_get_gvariant (tree->children[0]);
2332 else
2333 child = NULL;
2335 child_type = g_variant_type_element (type);
2337 if (child != NULL && randomly (0.5))
2338 child_type = NULL;
2340 result = g_variant_new_maybe (child_type, child);
2342 break;
2344 case G_VARIANT_TYPE_INFO_CHAR_ARRAY:
2346 const GVariantType *child_type;
2347 GVariant **children;
2348 gint i;
2350 children = g_new (GVariant *, tree->n_children);
2351 for (i = 0; i < tree->n_children; i++)
2352 children[i] = tree_instance_get_gvariant (tree->children[i]);
2354 child_type = g_variant_type_element (type);
2356 if (i > 0 && randomly (0.5))
2357 child_type = NULL;
2359 result = g_variant_new_array (child_type, children, tree->n_children);
2360 g_free (children);
2362 break;
2364 case G_VARIANT_TYPE_INFO_CHAR_TUPLE:
2366 GVariant **children;
2367 gint i;
2369 children = g_new (GVariant *, tree->n_children);
2370 for (i = 0; i < tree->n_children; i++)
2371 children[i] = tree_instance_get_gvariant (tree->children[i]);
2373 result = g_variant_new_tuple (children, tree->n_children);
2374 g_free (children);
2376 break;
2378 case G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY:
2380 GVariant *key, *val;
2382 g_assert (tree->n_children == 2);
2384 key = tree_instance_get_gvariant (tree->children[0]);
2385 val = tree_instance_get_gvariant (tree->children[1]);
2387 result = g_variant_new_dict_entry (key, val);
2389 break;
2391 case G_VARIANT_TYPE_INFO_CHAR_VARIANT:
2393 GVariant *value;
2395 g_assert (tree->n_children == 1);
2397 value = tree_instance_get_gvariant (tree->children[0]);
2398 result = g_variant_new_variant (value);
2400 break;
2402 case 'b':
2403 result = g_variant_new_boolean (tree->data.integer > 0);
2404 break;
2406 case 'y':
2407 result = g_variant_new_byte (tree->data.integer);
2408 break;
2410 case 'n':
2411 result = g_variant_new_int16 (tree->data.integer);
2412 break;
2414 case 'q':
2415 result = g_variant_new_uint16 (tree->data.integer);
2416 break;
2418 case 'i':
2419 result = g_variant_new_int32 (tree->data.integer);
2420 break;
2422 case 'u':
2423 result = g_variant_new_uint32 (tree->data.integer);
2424 break;
2426 case 'x':
2427 result = g_variant_new_int64 (tree->data.integer);
2428 break;
2430 case 't':
2431 result = g_variant_new_uint64 (tree->data.integer);
2432 break;
2434 case 'h':
2435 result = g_variant_new_handle (tree->data.integer);
2436 break;
2438 case 'd':
2439 result = g_variant_new_double (tree->data.floating);
2440 break;
2442 case 's':
2443 result = g_variant_new_string (tree->data.string);
2444 break;
2446 case 'o':
2447 result = g_variant_new_object_path (tree->data.string);
2448 break;
2450 case 'g':
2451 result = g_variant_new_signature (tree->data.string);
2452 break;
2454 default:
2455 g_assert_not_reached ();
2458 return result;
2461 static gboolean
2462 tree_instance_check_gvariant (TreeInstance *tree,
2463 GVariant *value)
2465 const GVariantType *type;
2467 type = (GVariantType *) g_variant_type_info_get_type_string (tree->info);
2468 g_assert (g_variant_is_of_type (value, type));
2470 switch (g_variant_type_info_get_type_char (tree->info))
2472 case G_VARIANT_TYPE_INFO_CHAR_MAYBE:
2474 GVariant *child;
2475 gboolean equal;
2477 child = g_variant_get_maybe (value);
2479 if (child != NULL && tree->n_children == 1)
2480 equal = tree_instance_check_gvariant (tree->children[0], child);
2481 else if (child == NULL && tree->n_children == 0)
2482 equal = TRUE;
2483 else
2484 equal = FALSE;
2486 if (child != NULL)
2487 g_variant_unref (child);
2489 return equal;
2491 break;
2493 case G_VARIANT_TYPE_INFO_CHAR_ARRAY:
2494 case G_VARIANT_TYPE_INFO_CHAR_TUPLE:
2495 case G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY:
2497 gsize i;
2499 if (g_variant_n_children (value) != tree->n_children)
2500 return FALSE;
2502 for (i = 0; i < tree->n_children; i++)
2504 GVariant *child;
2505 gboolean equal;
2507 child = g_variant_get_child_value (value, i);
2508 equal = tree_instance_check_gvariant (tree->children[i], child);
2509 g_variant_unref (child);
2511 if (!equal)
2512 return FALSE;
2515 return TRUE;
2517 break;
2519 case G_VARIANT_TYPE_INFO_CHAR_VARIANT:
2521 const gchar *str1, *str2;
2522 GVariant *child;
2523 gboolean equal;
2525 child = g_variant_get_variant (value);
2526 str1 = g_variant_get_type_string (child);
2527 str2 = g_variant_type_info_get_type_string (tree->children[0]->info);
2528 /* GVariant only keeps one copy of type strings around */
2529 equal = str1 == str2 &&
2530 tree_instance_check_gvariant (tree->children[0], child);
2532 g_variant_unref (child);
2534 return equal;
2536 break;
2538 case 'b':
2539 return g_variant_get_boolean (value) == tree->data.integer;
2541 case 'y':
2542 return g_variant_get_byte (value) == (guchar) tree->data.integer;
2544 case 'n':
2545 return g_variant_get_int16 (value) == (gint16) tree->data.integer;
2547 case 'q':
2548 return g_variant_get_uint16 (value) == (guint16) tree->data.integer;
2550 case 'i':
2551 return g_variant_get_int32 (value) == (gint32) tree->data.integer;
2553 case 'u':
2554 return g_variant_get_uint32 (value) == (guint32) tree->data.integer;
2556 case 'x':
2557 return g_variant_get_int64 (value) == (gint64) tree->data.integer;
2559 case 't':
2560 return g_variant_get_uint64 (value) == (guint64) tree->data.integer;
2562 case 'h':
2563 return g_variant_get_handle (value) == (gint32) tree->data.integer;
2565 case 'd':
2567 gdouble floating = g_variant_get_double (value);
2569 return memcmp (&floating, &tree->data.floating, sizeof floating) == 0;
2572 case 's':
2573 case 'o':
2574 case 'g':
2575 return strcmp (g_variant_get_string (value, NULL),
2576 tree->data.string) == 0;
2578 default:
2579 g_assert_not_reached ();
2583 static void
2584 tree_instance_build_gvariant (TreeInstance *tree,
2585 GVariantBuilder *builder,
2586 gboolean guess_ok)
2588 const GVariantType *type;
2590 type = (GVariantType *) g_variant_type_info_get_type_string (tree->info);
2592 if (g_variant_type_is_container (type))
2594 gsize i;
2596 /* force GVariantBuilder to guess the type half the time */
2597 if (guess_ok && randomly (0.5))
2599 if (g_variant_type_is_array (type) && tree->n_children)
2600 type = G_VARIANT_TYPE_ARRAY;
2602 if (g_variant_type_is_maybe (type) && tree->n_children)
2603 type = G_VARIANT_TYPE_MAYBE;
2605 if (g_variant_type_is_tuple (type))
2606 type = G_VARIANT_TYPE_TUPLE;
2608 if (g_variant_type_is_dict_entry (type))
2609 type = G_VARIANT_TYPE_DICT_ENTRY;
2611 else
2612 guess_ok = FALSE;
2614 g_variant_builder_open (builder, type);
2616 for (i = 0; i < tree->n_children; i++)
2617 tree_instance_build_gvariant (tree->children[i], builder, guess_ok);
2619 g_variant_builder_close (builder);
2621 else
2622 g_variant_builder_add_value (builder, tree_instance_get_gvariant (tree));
2626 static gboolean
2627 tree_instance_check_iter (TreeInstance *tree,
2628 GVariantIter *iter)
2630 GVariant *value;
2632 value = g_variant_iter_next_value (iter);
2634 if (g_variant_is_container (value))
2636 gsize i;
2638 iter = g_variant_iter_new (value);
2639 g_variant_unref (value);
2641 if (g_variant_iter_n_children (iter) != tree->n_children)
2643 g_variant_iter_free (iter);
2644 return FALSE;
2647 for (i = 0; i < tree->n_children; i++)
2648 if (!tree_instance_check_iter (tree->children[i], iter))
2650 g_variant_iter_free (iter);
2651 return FALSE;
2654 g_assert (g_variant_iter_next_value (iter) == NULL);
2655 g_variant_iter_free (iter);
2657 return TRUE;
2660 else
2662 gboolean equal;
2664 equal = tree_instance_check_gvariant (tree, value);
2665 g_variant_unref (value);
2667 return equal;
2671 static void
2672 test_container (void)
2674 TreeInstance *tree;
2675 GVariant *value;
2676 gchar *s1, *s2;
2678 tree = tree_instance_new (NULL, 3);
2679 value = g_variant_ref_sink (tree_instance_get_gvariant (tree));
2681 s1 = g_variant_print (value, TRUE);
2682 g_assert (tree_instance_check_gvariant (tree, value));
2684 g_variant_get_data (value);
2686 s2 = g_variant_print (value, TRUE);
2687 g_assert (tree_instance_check_gvariant (tree, value));
2689 g_assert_cmpstr (s1, ==, s2);
2691 if (g_variant_is_container (value))
2693 GVariantBuilder builder;
2694 GVariantIter iter;
2695 GVariant *built;
2696 GVariant *val;
2697 gchar *s3;
2699 g_variant_builder_init (&builder, G_VARIANT_TYPE_VARIANT);
2700 tree_instance_build_gvariant (tree, &builder, TRUE);
2701 built = g_variant_builder_end (&builder);
2702 g_variant_ref_sink (built);
2703 g_variant_get_data (built);
2704 val = g_variant_get_variant (built);
2706 s3 = g_variant_print (val, TRUE);
2707 g_assert_cmpstr (s1, ==, s3);
2709 g_variant_iter_init (&iter, built);
2710 g_assert (tree_instance_check_iter (tree, &iter));
2711 g_assert (g_variant_iter_next_value (&iter) == NULL);
2713 g_variant_unref (built);
2714 g_variant_unref (val);
2715 g_free (s3);
2718 tree_instance_free (tree);
2719 g_variant_unref (value);
2720 g_free (s2);
2721 g_free (s1);
2724 static void
2725 test_string (void)
2727 /* Test some different methods of creating strings */
2728 GVariant *v;
2730 v = g_variant_new_string ("foo");
2731 g_assert_cmpstr (g_variant_get_string (v, NULL), ==, "foo");
2732 g_variant_unref (v);
2735 v = g_variant_new_take_string (g_strdup ("foo"));
2736 g_assert_cmpstr (g_variant_get_string (v, NULL), ==, "foo");
2737 g_variant_unref (v);
2739 v = g_variant_new_printf ("%s %d", "foo", 123);
2740 g_assert_cmpstr (g_variant_get_string (v, NULL), ==, "foo 123");
2741 g_variant_unref (v);
2744 static void
2745 test_utf8 (void)
2747 const gchar invalid[] = "hello\xffworld";
2748 GVariant *value;
2750 /* ensure that the test data is not valid utf8... */
2751 g_assert (!g_utf8_validate (invalid, -1, NULL));
2753 /* load the data untrusted */
2754 value = g_variant_new_from_data (G_VARIANT_TYPE_STRING,
2755 invalid, sizeof invalid,
2756 FALSE, NULL, NULL);
2758 /* ensure that the problem is caught and we get valid UTF-8 */
2759 g_assert (g_utf8_validate (g_variant_get_string (value, NULL), -1, NULL));
2760 g_variant_unref (value);
2763 /* now load it trusted */
2764 value = g_variant_new_from_data (G_VARIANT_TYPE_STRING,
2765 invalid, sizeof invalid,
2766 TRUE, NULL, NULL);
2768 /* ensure we get the invalid data (ie: make sure that time wasn't
2769 * wasted on validating data that was marked as trusted)
2771 g_assert (g_variant_get_string (value, NULL) == invalid);
2772 g_variant_unref (value);
2775 static void
2776 test_containers (void)
2778 gint i;
2780 for (i = 0; i < 100; i++)
2782 test_container ();
2785 g_variant_type_info_assert_no_infos ();
2788 static void
2789 test_format_strings (void)
2791 GVariantType *type;
2792 const gchar *end;
2794 g_assert (g_variant_format_string_scan ("i", NULL, &end) && *end == '\0');
2795 g_assert (g_variant_format_string_scan ("@i", NULL, &end) && *end == '\0');
2796 g_assert (g_variant_format_string_scan ("@ii", NULL, &end) && *end == 'i');
2797 g_assert (g_variant_format_string_scan ("^a&s", NULL, &end) && *end == '\0');
2798 g_assert (g_variant_format_string_scan ("(^as)", NULL, &end) &&
2799 *end == '\0');
2800 g_assert (!g_variant_format_string_scan ("(^s)", NULL, &end));
2801 g_assert (!g_variant_format_string_scan ("(^a)", NULL, &end));
2802 g_assert (!g_variant_format_string_scan ("(z)", NULL, &end));
2803 g_assert (!g_variant_format_string_scan ("az", NULL, &end));
2804 g_assert (!g_variant_format_string_scan ("{**}", NULL, &end));
2805 g_assert (!g_variant_format_string_scan ("{@**}", NULL, &end));
2806 g_assert (g_variant_format_string_scan ("{@y*}", NULL, &end) &&
2807 *end == '\0');
2808 g_assert (g_variant_format_string_scan ("{yv}", NULL, &end) &&
2809 *end == '\0');
2810 g_assert (!g_variant_format_string_scan ("{&?v}", NULL, &end));
2811 g_assert (g_variant_format_string_scan ("{@?v}", NULL, &end) &&
2812 *end == '\0');
2813 g_assert (!g_variant_format_string_scan ("{&@sv}", NULL, &end));
2814 g_assert (!g_variant_format_string_scan ("{@&sv}", NULL, &end));
2815 g_assert (g_variant_format_string_scan ("{&sv}", NULL, &end) &&
2816 *end == '\0');
2817 g_assert (!g_variant_format_string_scan ("{vv}", NULL, &end));
2818 g_assert (!g_variant_format_string_scan ("{y}", NULL, &end));
2819 g_assert (!g_variant_format_string_scan ("{yyy}", NULL, &end));
2820 g_assert (!g_variant_format_string_scan ("{ya}", NULL, &end));
2821 g_assert (g_variant_format_string_scan ("&s", NULL, &end) && *end == '\0');
2822 g_assert (!g_variant_format_string_scan ("&as", NULL, &end));
2823 g_assert (!g_variant_format_string_scan ("@z", NULL, &end));
2824 g_assert (!g_variant_format_string_scan ("az", NULL, &end));
2825 g_assert (!g_variant_format_string_scan ("a&s", NULL, &end));
2827 type = g_variant_format_string_scan_type ("mm(@xy^a&s*?@?)", NULL, &end);
2828 g_assert (type && *end == '\0');
2829 g_assert (g_variant_type_equal (type, G_VARIANT_TYPE ("mm(xyas*?\?)")));
2830 g_variant_type_free (type);
2832 type = g_variant_format_string_scan_type ("mm(@xy^a&*?@?)", NULL, NULL);
2833 g_assert (type == NULL);
2836 static void
2837 do_failed_test (const char *test,
2838 const gchar *pattern)
2840 g_test_trap_subprocess (test, 1000000, 0);
2841 g_test_trap_assert_failed ();
2842 g_test_trap_assert_stderr (pattern);
2845 static void
2846 test_invalid_varargs (void)
2848 GVariant *value;
2849 const gchar *end;
2851 if (!g_test_undefined ())
2852 return;
2854 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
2855 "*GVariant format string*");
2856 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
2857 "*valid_format_string*");
2858 value = g_variant_new ("z");
2859 g_test_assert_expected_messages ();
2860 g_assert (value == NULL);
2862 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
2863 "*valid GVariant format string as a prefix*");
2864 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
2865 "*valid_format_string*");
2866 value = g_variant_new_va ("z", &end, NULL);
2867 g_test_assert_expected_messages ();
2868 g_assert (value == NULL);
2870 value = g_variant_new ("y", 'a');
2871 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
2872 "*type of 'q' but * has a type of 'y'*");
2873 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
2874 "*valid_format_string*");
2875 g_variant_get (value, "q");
2876 g_test_assert_expected_messages ();
2877 g_variant_unref (value);
2880 static void
2881 check_and_free (GVariant *value,
2882 const gchar *str)
2884 gchar *valstr = g_variant_print (value, FALSE);
2885 g_assert_cmpstr (str, ==, valstr);
2886 g_variant_unref (value);
2887 g_free (valstr);
2890 static void
2891 test_varargs_empty_array (void)
2893 g_variant_new ("(a{s*})", NULL);
2895 g_assert_not_reached ();
2898 static void
2899 test_varargs (void)
2902 GVariantBuilder array;
2904 g_variant_builder_init (&array, G_VARIANT_TYPE_ARRAY);
2905 g_variant_builder_add_parsed (&array, "{'size', <(%i, %i)> }", 800, 600);
2906 g_variant_builder_add (&array, "{sv}", "title",
2907 g_variant_new_string ("Test case"));
2908 g_variant_builder_add_value (&array,
2909 g_variant_new_dict_entry (g_variant_new_string ("temperature"),
2910 g_variant_new_variant (
2911 g_variant_new_double (37.5))));
2912 check_and_free (g_variant_new ("(ma{sv}m(a{sv})ma{sv}ii)",
2913 NULL, FALSE, NULL, &array, 7777, 8888),
2914 "(nothing, nothing, {'size': <(800, 600)>, "
2915 "'title': <'Test case'>, "
2916 "'temperature': <37.5>}, "
2917 "7777, 8888)");
2919 check_and_free (g_variant_new ("(imimimmimmimmi)",
2920 123,
2921 FALSE, 321,
2922 TRUE, 123,
2923 FALSE, TRUE, 321,
2924 TRUE, FALSE, 321,
2925 TRUE, TRUE, 123),
2926 "(123, nothing, 123, nothing, just nothing, 123)");
2928 check_and_free (g_variant_new ("(ybnixd)",
2929 'a', 1, 22, 33, (guint64) 44, 5.5),
2930 "(0x61, true, 22, 33, 44, 5.5)");
2932 check_and_free (g_variant_new ("(@y?*rv)",
2933 g_variant_new ("y", 'a'),
2934 g_variant_new ("y", 'b'),
2935 g_variant_new ("y", 'c'),
2936 g_variant_new ("(y)", 'd'),
2937 g_variant_new ("y", 'e')),
2938 "(0x61, 0x62, 0x63, (0x64,), <byte 0x65>)");
2942 GVariantBuilder array;
2943 GVariantIter iter;
2944 GVariant *value;
2945 gchar *number;
2946 gboolean just;
2947 gint i, val;
2949 g_variant_builder_init (&array, G_VARIANT_TYPE_ARRAY);
2950 for (i = 0; i < 100; i++)
2952 number = g_strdup_printf ("%d", i);
2953 g_variant_builder_add (&array, "s", number);
2954 g_free (number);
2957 value = g_variant_builder_end (&array);
2958 g_variant_iter_init (&iter, value);
2960 i = 0;
2961 while (g_variant_iter_loop (&iter, "s", &number))
2963 gchar *check = g_strdup_printf ("%d", i++);
2964 g_assert_cmpstr (number, ==, check);
2965 g_free (check);
2967 g_assert (number == NULL);
2968 g_assert (i == 100);
2970 g_variant_unref (value);
2972 g_variant_builder_init (&array, G_VARIANT_TYPE_ARRAY);
2973 for (i = 0; i < 100; i++)
2974 g_variant_builder_add (&array, "mi", i % 2 == 0, i);
2975 value = g_variant_builder_end (&array);
2977 i = 0;
2978 g_variant_iter_init (&iter, value);
2979 while (g_variant_iter_loop (&iter, "mi", NULL, &val))
2980 g_assert (val == i++ || val == 0);
2981 g_assert (i == 100);
2983 i = 0;
2984 g_variant_iter_init (&iter, value);
2985 while (g_variant_iter_loop (&iter, "mi", &just, &val))
2987 gint this = i++;
2989 if (this % 2 == 0)
2991 g_assert (just);
2992 g_assert (val == this);
2994 else
2996 g_assert (!just);
2997 g_assert (val == 0);
3000 g_assert (i == 100);
3002 g_variant_unref (value);
3006 const gchar *strvector[] = {"/hello", "/world", NULL};
3007 const gchar *test_strs[] = {"/foo", "/bar", "/baz" };
3008 GVariantBuilder builder;
3009 GVariantIter *array;
3010 GVariantIter tuple;
3011 const gchar **strv;
3012 gchar **my_strv;
3013 GVariant *value;
3014 gchar *str;
3015 gint i;
3017 g_variant_builder_init (&builder, G_VARIANT_TYPE ("as"));
3018 g_variant_builder_add (&builder, "s", "/foo");
3019 g_variant_builder_add (&builder, "s", "/bar");
3020 g_variant_builder_add (&builder, "s", "/baz");
3021 value = g_variant_new("(as^as^a&s)", &builder, strvector, strvector);
3022 g_variant_iter_init (&tuple, value);
3023 g_variant_iter_next (&tuple, "as", &array);
3025 i = 0;
3026 while (g_variant_iter_loop (array, "s", &str))
3027 g_assert_cmpstr (str, ==, test_strs[i++]);
3028 g_assert (i == 3);
3030 g_variant_iter_free (array);
3032 /* start over */
3033 g_variant_iter_init (&tuple, value);
3034 g_variant_iter_next (&tuple, "as", &array);
3036 i = 0;
3037 while (g_variant_iter_loop (array, "&s", &str))
3038 g_assert_cmpstr (str, ==, test_strs[i++]);
3039 g_assert (i == 3);
3041 g_variant_iter_free (array);
3043 g_variant_iter_next (&tuple, "^a&s", &strv);
3044 g_variant_iter_next (&tuple, "^as", &my_strv);
3046 g_assert_cmpstr (strv[0], ==, "/hello");
3047 g_assert_cmpstr (strv[1], ==, "/world");
3048 g_assert (strv[2] == NULL);
3049 g_assert_cmpstr (my_strv[0], ==, "/hello");
3050 g_assert_cmpstr (my_strv[1], ==, "/world");
3051 g_assert (my_strv[2] == NULL);
3053 g_variant_unref (value);
3054 g_strfreev (my_strv);
3055 g_free (strv);
3059 const gchar *strvector[] = {"/hello", "/world", NULL};
3060 const gchar *test_strs[] = {"/foo", "/bar", "/baz" };
3061 GVariantBuilder builder;
3062 GVariantIter *array;
3063 GVariantIter tuple;
3064 const gchar **strv;
3065 gchar **my_strv;
3066 GVariant *value;
3067 gchar *str;
3068 gint i;
3070 g_variant_builder_init (&builder, G_VARIANT_TYPE_OBJECT_PATH_ARRAY);
3071 g_variant_builder_add (&builder, "o", "/foo");
3072 g_variant_builder_add (&builder, "o", "/bar");
3073 g_variant_builder_add (&builder, "o", "/baz");
3074 value = g_variant_new("(ao^ao^a&o)", &builder, strvector, strvector);
3075 g_variant_iter_init (&tuple, value);
3076 g_variant_iter_next (&tuple, "ao", &array);
3078 i = 0;
3079 while (g_variant_iter_loop (array, "o", &str))
3080 g_assert_cmpstr (str, ==, test_strs[i++]);
3081 g_assert (i == 3);
3083 g_variant_iter_free (array);
3085 /* start over */
3086 g_variant_iter_init (&tuple, value);
3087 g_variant_iter_next (&tuple, "ao", &array);
3089 i = 0;
3090 while (g_variant_iter_loop (array, "&o", &str))
3091 g_assert_cmpstr (str, ==, test_strs[i++]);
3092 g_assert (i == 3);
3094 g_variant_iter_free (array);
3096 g_variant_iter_next (&tuple, "^a&o", &strv);
3097 g_variant_iter_next (&tuple, "^ao", &my_strv);
3099 g_assert_cmpstr (strv[0], ==, "/hello");
3100 g_assert_cmpstr (strv[1], ==, "/world");
3101 g_assert (strv[2] == NULL);
3102 g_assert_cmpstr (my_strv[0], ==, "/hello");
3103 g_assert_cmpstr (my_strv[1], ==, "/world");
3104 g_assert (my_strv[2] == NULL);
3106 g_variant_unref (value);
3107 g_strfreev (my_strv);
3108 g_free (strv);
3112 const gchar *strvector[] = { "i", "ii", "iii", "iv", "v", "vi", NULL };
3113 GVariantBuilder builder;
3114 GVariantIter iter;
3115 GVariantIter *i2;
3116 GVariantIter *i3;
3117 GVariant *value;
3118 GVariant *sub;
3119 gchar **strv;
3120 gint i;
3122 g_variant_builder_init (&builder, G_VARIANT_TYPE ("aas"));
3123 g_variant_builder_open (&builder, G_VARIANT_TYPE ("as"));
3124 for (i = 0; i < 6; i++)
3125 if (i & 1)
3126 g_variant_builder_add (&builder, "s", strvector[i]);
3127 else
3128 g_variant_builder_add (&builder, "&s", strvector[i]);
3129 g_variant_builder_close (&builder);
3130 g_variant_builder_add (&builder, "^as", strvector);
3131 g_variant_builder_add (&builder, "^as", strvector);
3132 value = g_variant_new ("aas", &builder);
3134 g_variant_iter_init (&iter, value);
3135 while (g_variant_iter_loop (&iter, "^as", &strv))
3136 for (i = 0; i < 6; i++)
3137 g_assert_cmpstr (strv[i], ==, strvector[i]);
3139 g_variant_iter_init (&iter, value);
3140 while (g_variant_iter_loop (&iter, "^a&s", &strv))
3141 for (i = 0; i < 6; i++)
3142 g_assert_cmpstr (strv[i], ==, strvector[i]);
3144 g_variant_iter_init (&iter, value);
3145 while (g_variant_iter_loop (&iter, "as", &i2))
3147 gchar *str;
3149 i = 0;
3150 while (g_variant_iter_loop (i2, "s", &str))
3151 g_assert_cmpstr (str, ==, strvector[i++]);
3152 g_assert (i == 6);
3155 g_variant_iter_init (&iter, value);
3156 i3 = g_variant_iter_copy (&iter);
3157 while (g_variant_iter_loop (&iter, "@as", &sub))
3159 gchar *str = g_variant_print (sub, TRUE);
3160 g_assert_cmpstr (str, ==,
3161 "['i', 'ii', 'iii', 'iv', 'v', 'vi']");
3162 g_free (str);
3165 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
3166 "*NULL has already been returned*");
3167 g_variant_iter_next_value (&iter);
3168 g_test_assert_expected_messages ();
3170 while (g_variant_iter_loop (i3, "*", &sub))
3172 gchar *str = g_variant_print (sub, TRUE);
3173 g_assert_cmpstr (str, ==,
3174 "['i', 'ii', 'iii', 'iv', 'v', 'vi']");
3175 g_free (str);
3178 g_variant_iter_free (i3);
3180 for (i = 0; i < g_variant_n_children (value); i++)
3182 gint j;
3184 g_variant_get_child (value, i, "*", &sub);
3186 for (j = 0; j < g_variant_n_children (sub); j++)
3188 const gchar *str = NULL;
3189 GVariant *cval;
3191 g_variant_get_child (sub, j, "&s", &str);
3192 g_assert_cmpstr (str, ==, strvector[j]);
3194 cval = g_variant_get_child_value (sub, j);
3195 g_variant_get (cval, "&s", &str);
3196 g_assert_cmpstr (str, ==, strvector[j]);
3197 g_variant_unref (cval);
3200 g_variant_unref (sub);
3203 g_variant_unref (value);
3207 gboolean justs[10];
3208 GVariant *value;
3210 GVariant *vval;
3211 guchar byteval;
3212 gboolean bval;
3213 gint16 i16val;
3214 guint16 u16val;
3215 gint32 i32val;
3216 guint32 u32val;
3217 gint64 i64val;
3218 guint64 u64val;
3219 gdouble dval;
3220 gint32 hval;
3222 /* test all 'nothing' */
3223 value = g_variant_new ("(mymbmnmqmimumxmtmhmdmv)",
3224 FALSE, 'a',
3225 FALSE, TRUE,
3226 FALSE, (gint16) 123,
3227 FALSE, (guint16) 123,
3228 FALSE, (gint32) 123,
3229 FALSE, (guint32) 123,
3230 FALSE, (gint64) 123,
3231 FALSE, (guint64) 123,
3232 FALSE, (gint32) -1,
3233 FALSE, (gdouble) 37.5,
3234 NULL);
3236 /* both NULL */
3237 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3238 NULL, NULL,
3239 NULL, NULL,
3240 NULL, NULL,
3241 NULL, NULL,
3242 NULL, NULL,
3243 NULL, NULL,
3244 NULL, NULL,
3245 NULL, NULL,
3246 NULL, NULL,
3247 NULL, NULL,
3248 NULL);
3250 /* NULL values */
3251 memset (justs, 1, sizeof justs);
3252 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3253 &justs[0], NULL,
3254 &justs[1], NULL,
3255 &justs[2], NULL,
3256 &justs[3], NULL,
3257 &justs[4], NULL,
3258 &justs[5], NULL,
3259 &justs[6], NULL,
3260 &justs[7], NULL,
3261 &justs[8], NULL,
3262 &justs[9], NULL,
3263 NULL);
3264 g_assert (!(justs[0] || justs[1] || justs[2] || justs[3] || justs[4] ||
3265 justs[5] || justs[6] || justs[7] || justs[8] || justs[9]));
3267 /* both non-NULL */
3268 memset (justs, 1, sizeof justs);
3269 byteval = i16val = u16val = i32val = u32val = i64val = u64val = hval = 88;
3270 vval = (void *) 1;
3271 bval = TRUE;
3272 dval = 88.88;
3273 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3274 &justs[0], &byteval,
3275 &justs[1], &bval,
3276 &justs[2], &i16val,
3277 &justs[3], &u16val,
3278 &justs[4], &i32val,
3279 &justs[5], &u32val,
3280 &justs[6], &i64val,
3281 &justs[7], &u64val,
3282 &justs[8], &hval,
3283 &justs[9], &dval,
3284 &vval);
3285 g_assert (!(justs[0] || justs[1] || justs[2] || justs[3] || justs[4] ||
3286 justs[5] || justs[6] || justs[7] || justs[8] || justs[9]));
3287 g_assert (byteval == '\0' && bval == FALSE);
3288 g_assert (i16val == 0 && u16val == 0 && i32val == 0 &&
3289 u32val == 0 && i64val == 0 && u64val == 0 &&
3290 hval == 0 && dval == 0.0);
3291 g_assert (vval == NULL);
3293 /* NULL justs */
3294 byteval = i16val = u16val = i32val = u32val = i64val = u64val = hval = 88;
3295 vval = (void *) 1;
3296 bval = TRUE;
3297 dval = 88.88;
3298 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3299 NULL, &byteval,
3300 NULL, &bval,
3301 NULL, &i16val,
3302 NULL, &u16val,
3303 NULL, &i32val,
3304 NULL, &u32val,
3305 NULL, &i64val,
3306 NULL, &u64val,
3307 NULL, &hval,
3308 NULL, &dval,
3309 &vval);
3310 g_assert (byteval == '\0' && bval == FALSE);
3311 g_assert (i16val == 0 && u16val == 0 && i32val == 0 &&
3312 u32val == 0 && i64val == 0 && u64val == 0 &&
3313 hval == 0 && dval == 0.0);
3314 g_assert (vval == NULL);
3316 g_variant_unref (value);
3319 /* test all 'just' */
3320 value = g_variant_new ("(mymbmnmqmimumxmtmhmdmv)",
3321 TRUE, 'a',
3322 TRUE, TRUE,
3323 TRUE, (gint16) 123,
3324 TRUE, (guint16) 123,
3325 TRUE, (gint32) 123,
3326 TRUE, (guint32) 123,
3327 TRUE, (gint64) 123,
3328 TRUE, (guint64) 123,
3329 TRUE, (gint32) -1,
3330 TRUE, (gdouble) 37.5,
3331 g_variant_new ("()"));
3333 /* both NULL */
3334 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3335 NULL, NULL,
3336 NULL, NULL,
3337 NULL, NULL,
3338 NULL, NULL,
3339 NULL, NULL,
3340 NULL, NULL,
3341 NULL, NULL,
3342 NULL, NULL,
3343 NULL, NULL,
3344 NULL, NULL,
3345 NULL);
3347 /* NULL values */
3348 memset (justs, 0, sizeof justs);
3349 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3350 &justs[0], NULL,
3351 &justs[1], NULL,
3352 &justs[2], NULL,
3353 &justs[3], NULL,
3354 &justs[4], NULL,
3355 &justs[5], NULL,
3356 &justs[6], NULL,
3357 &justs[7], NULL,
3358 &justs[8], NULL,
3359 &justs[9], NULL,
3360 NULL);
3361 g_assert (justs[0] && justs[1] && justs[2] && justs[3] && justs[4] &&
3362 justs[5] && justs[6] && justs[7] && justs[8] && justs[9]);
3364 /* both non-NULL */
3365 memset (justs, 0, sizeof justs);
3366 byteval = i16val = u16val = i32val = u32val = i64val = u64val = hval = 88;
3367 vval = (void *) 1;
3368 bval = FALSE;
3369 dval = 88.88;
3370 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3371 &justs[0], &byteval,
3372 &justs[1], &bval,
3373 &justs[2], &i16val,
3374 &justs[3], &u16val,
3375 &justs[4], &i32val,
3376 &justs[5], &u32val,
3377 &justs[6], &i64val,
3378 &justs[7], &u64val,
3379 &justs[8], &hval,
3380 &justs[9], &dval,
3381 &vval);
3382 g_assert (justs[0] && justs[1] && justs[2] && justs[3] && justs[4] &&
3383 justs[5] && justs[6] && justs[7] && justs[8] && justs[9]);
3384 g_assert (byteval == 'a' && bval == TRUE);
3385 g_assert (i16val == 123 && u16val == 123 && i32val == 123 &&
3386 u32val == 123 && i64val == 123 && u64val == 123 &&
3387 hval == -1 && dval == 37.5);
3388 g_assert (g_variant_is_of_type (vval, G_VARIANT_TYPE_UNIT));
3389 g_variant_unref (vval);
3391 /* NULL justs */
3392 byteval = i16val = u16val = i32val = u32val = i64val = u64val = hval = 88;
3393 vval = (void *) 1;
3394 bval = TRUE;
3395 dval = 88.88;
3396 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3397 NULL, &byteval,
3398 NULL, &bval,
3399 NULL, &i16val,
3400 NULL, &u16val,
3401 NULL, &i32val,
3402 NULL, &u32val,
3403 NULL, &i64val,
3404 NULL, &u64val,
3405 NULL, &hval,
3406 NULL, &dval,
3407 &vval);
3408 g_assert (byteval == 'a' && bval == TRUE);
3409 g_assert (i16val == 123 && u16val == 123 && i32val == 123 &&
3410 u32val == 123 && i64val == 123 && u64val == 123 &&
3411 hval == -1 && dval == 37.5);
3412 g_assert (g_variant_is_of_type (vval, G_VARIANT_TYPE_UNIT));
3413 g_variant_unref (vval);
3415 g_variant_unref (value);
3419 GVariant *value;
3420 gchar *str;
3422 value = g_variant_new ("(masas)", NULL, NULL);
3423 g_variant_ref_sink (value);
3425 str = g_variant_print (value, TRUE);
3426 g_assert_cmpstr (str, ==, "(@mas nothing, @as [])");
3427 g_variant_unref (value);
3428 g_free (str);
3430 do_failed_test ("/gvariant/varargs/subprocess/empty-array",
3431 "*which type of empty array*");
3434 g_variant_type_info_assert_no_infos ();
3437 static void
3438 hash_get (GVariant *value,
3439 const gchar *format,
3440 ...)
3442 const gchar *endptr = NULL;
3443 gboolean hash;
3444 va_list ap;
3446 hash = g_str_has_suffix (format, "#");
3448 va_start (ap, format);
3449 g_variant_get_va (value, format, hash ? &endptr : NULL, &ap);
3450 va_end (ap);
3452 if (hash)
3453 g_assert (*endptr == '#');
3456 static GVariant *
3457 hash_new (const gchar *format,
3458 ...)
3460 const gchar *endptr = NULL;
3461 GVariant *value;
3462 gboolean hash;
3463 va_list ap;
3465 hash = g_str_has_suffix (format, "#");
3467 va_start (ap, format);
3468 value = g_variant_new_va (format, hash ? &endptr : NULL, &ap);
3469 va_end (ap);
3471 if (hash)
3472 g_assert (*endptr == '#');
3474 return value;
3477 static void
3478 test_valist (void)
3480 GVariant *value;
3481 gint32 x;
3483 x = 0;
3484 value = hash_new ("i", 234);
3485 hash_get (value, "i", &x);
3486 g_assert (x == 234);
3487 g_variant_unref (value);
3489 x = 0;
3490 value = hash_new ("i#", 234);
3491 hash_get (value, "i#", &x);
3492 g_assert (x == 234);
3493 g_variant_unref (value);
3495 g_variant_type_info_assert_no_infos ();
3498 static void
3499 test_builder_memory (void)
3501 GVariantBuilder *hb;
3502 GVariantBuilder sb;
3504 hb = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
3505 g_variant_builder_open (hb, G_VARIANT_TYPE_ARRAY);
3506 g_variant_builder_open (hb, G_VARIANT_TYPE_ARRAY);
3507 g_variant_builder_open (hb, G_VARIANT_TYPE_ARRAY);
3508 g_variant_builder_add (hb, "s", "some value");
3509 g_variant_builder_ref (hb);
3510 g_variant_builder_unref (hb);
3511 g_variant_builder_unref (hb);
3513 hb = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
3514 g_variant_builder_unref (hb);
3516 hb = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
3517 g_variant_builder_clear (hb);
3518 g_variant_builder_unref (hb);
3520 g_variant_builder_init (&sb, G_VARIANT_TYPE_ARRAY);
3521 g_variant_builder_open (&sb, G_VARIANT_TYPE_ARRAY);
3522 g_variant_builder_open (&sb, G_VARIANT_TYPE_ARRAY);
3523 g_variant_builder_add (&sb, "s", "some value");
3524 g_variant_builder_clear (&sb);
3526 g_variant_type_info_assert_no_infos ();
3529 static void
3530 test_hashing (void)
3532 GVariant *items[4096];
3533 GHashTable *table;
3534 gint i;
3536 table = g_hash_table_new_full (g_variant_hash, g_variant_equal,
3537 (GDestroyNotify ) g_variant_unref,
3538 NULL);
3540 for (i = 0; i < G_N_ELEMENTS (items); i++)
3542 TreeInstance *tree;
3543 gint j;
3545 again:
3546 tree = tree_instance_new (NULL, 0);
3547 items[i] = tree_instance_get_gvariant (tree);
3548 tree_instance_free (tree);
3550 for (j = 0; j < i; j++)
3551 if (g_variant_equal (items[i], items[j]))
3553 g_variant_unref (items[i]);
3554 goto again;
3557 g_hash_table_insert (table,
3558 g_variant_ref_sink (items[i]),
3559 GINT_TO_POINTER (i));
3562 for (i = 0; i < G_N_ELEMENTS (items); i++)
3564 gpointer result;
3566 result = g_hash_table_lookup (table, items[i]);
3567 g_assert_cmpint (GPOINTER_TO_INT (result), ==, i);
3570 g_hash_table_unref (table);
3572 g_variant_type_info_assert_no_infos ();
3575 static void
3576 test_gv_byteswap (void)
3578 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
3579 # define native16(x) x, 0
3580 # define swapped16(x) 0, x
3581 #else
3582 # define native16(x) 0, x
3583 # define swapped16(x) x, 0
3584 #endif
3585 /* all kinds of of crazy randomised testing already performed on the
3586 * byteswapper in the /gvariant/serialiser/byteswap test and all kinds
3587 * of crazy randomised testing performed against the serialiser
3588 * normalisation functions in the /gvariant/serialiser/fuzz/ tests.
3590 * just test a few simple cases here to make sure they each work
3592 guchar validbytes[] = { 'a', '\0', swapped16(66), 2,
3594 'b', '\0', swapped16(77), 2,
3595 5, 11 };
3596 guchar corruptbytes[] = { 'a', '\0', swapped16(66), 2,
3598 'b', '\0', swapped16(77), 2,
3599 6, 11 };
3600 guint valid_data[4], corrupt_data[4];
3601 GVariant *value, *swapped;
3602 gchar *string, *string2;
3604 memcpy (valid_data, validbytes, sizeof validbytes);
3605 memcpy (corrupt_data, corruptbytes, sizeof corruptbytes);
3607 /* trusted */
3608 value = g_variant_new_from_data (G_VARIANT_TYPE ("a(sn)"),
3609 valid_data, sizeof validbytes, TRUE,
3610 NULL, NULL);
3611 swapped = g_variant_byteswap (value);
3612 g_variant_unref (value);
3613 g_assert (g_variant_get_size (swapped) == 13);
3614 string = g_variant_print (swapped, FALSE);
3615 g_variant_unref (swapped);
3616 g_assert_cmpstr (string, ==, "[('a', 66), ('b', 77)]");
3617 g_free (string);
3619 /* untrusted but valid */
3620 value = g_variant_new_from_data (G_VARIANT_TYPE ("a(sn)"),
3621 valid_data, sizeof validbytes, FALSE,
3622 NULL, NULL);
3623 swapped = g_variant_byteswap (value);
3624 g_variant_unref (value);
3625 g_assert (g_variant_get_size (swapped) == 13);
3626 string = g_variant_print (swapped, FALSE);
3627 g_variant_unref (swapped);
3628 g_assert_cmpstr (string, ==, "[('a', 66), ('b', 77)]");
3629 g_free (string);
3631 /* untrusted, invalid */
3632 value = g_variant_new_from_data (G_VARIANT_TYPE ("a(sn)"),
3633 corrupt_data, sizeof corruptbytes, FALSE,
3634 NULL, NULL);
3635 string = g_variant_print (value, FALSE);
3636 swapped = g_variant_byteswap (value);
3637 g_variant_unref (value);
3638 g_assert (g_variant_get_size (swapped) == 13);
3639 value = g_variant_byteswap (swapped);
3640 g_variant_unref (swapped);
3641 string2 = g_variant_print (value, FALSE);
3642 g_assert (g_variant_get_size (value) == 13);
3643 g_variant_unref (value);
3644 g_assert_cmpstr (string, ==, string2);
3645 g_free (string2);
3646 g_free (string);
3649 static void
3650 test_parser (void)
3652 TreeInstance *tree;
3653 GVariant *parsed;
3654 GVariant *value;
3655 gchar *pt, *p;
3656 gchar *res;
3658 tree = tree_instance_new (NULL, 3);
3659 value = tree_instance_get_gvariant (tree);
3660 tree_instance_free (tree);
3662 pt = g_variant_print (value, TRUE);
3663 p = g_variant_print (value, FALSE);
3665 parsed = g_variant_parse (NULL, pt, NULL, NULL, NULL);
3666 res = g_variant_print (parsed, FALSE);
3667 g_assert_cmpstr (p, ==, res);
3668 g_variant_unref (parsed);
3669 g_free (res);
3671 parsed = g_variant_parse (g_variant_get_type (value), p,
3672 NULL, NULL, NULL);
3673 res = g_variant_print (parsed, TRUE);
3674 g_assert_cmpstr (pt, ==, res);
3675 g_variant_unref (parsed);
3676 g_free (res);
3678 g_variant_unref (value);
3679 g_free (pt);
3680 g_free (p);
3683 static void
3684 test_parses (void)
3686 gint i;
3688 for (i = 0; i < 100; i++)
3690 test_parser ();
3693 /* mini test */
3695 GError *error = NULL;
3696 gchar str[128];
3697 GVariant *val;
3698 gchar *p, *p2;
3700 for (i = 0; i < 127; i++)
3701 str[i] = i + 1;
3702 str[i] = 0;
3704 val = g_variant_new_string (str);
3705 p = g_variant_print (val, FALSE);
3706 g_variant_unref (val);
3708 val = g_variant_parse (NULL, p, NULL, NULL, &error);
3709 p2 = g_variant_print (val, FALSE);
3711 g_assert_cmpstr (str, ==, g_variant_get_string (val, NULL));
3712 g_assert_cmpstr (p, ==, p2);
3714 g_variant_unref (val);
3715 g_free (p2);
3716 g_free (p);
3719 /* another mini test */
3721 const gchar *end;
3722 GVariant *value;
3724 value = g_variant_parse (G_VARIANT_TYPE_INT32, "1 2 3", NULL, &end, NULL);
3725 g_assert_cmpint (g_variant_get_int32 (value), ==, 1);
3726 /* make sure endptr returning works */
3727 g_assert_cmpstr (end, ==, " 2 3");
3728 g_variant_unref (value);
3731 /* unicode mini test */
3733 /* ał𝄞 */
3734 const gchar orig[] = "a\xc5\x82\xf0\x9d\x84\x9e \t\n";
3735 GVariant *value;
3736 gchar *printed;
3738 value = g_variant_new_string (orig);
3739 printed = g_variant_print (value, FALSE);
3740 g_variant_unref (value);
3742 g_assert_cmpstr (printed, ==, "'a\xc5\x82\xf0\x9d\x84\x9e \\t\\n'");
3743 value = g_variant_parse (NULL, printed, NULL, NULL, NULL);
3744 g_assert_cmpstr (g_variant_get_string (value, NULL), ==, orig);
3745 g_variant_unref (value);
3746 g_free (printed);
3749 /* escapes */
3751 const gchar orig[] = " \342\200\254 \360\220\210\240 \a \b \f \n \r \t \v ";
3752 GVariant *value;
3753 gchar *printed;
3755 value = g_variant_new_string (orig);
3756 printed = g_variant_print (value, FALSE);
3757 g_variant_unref (value);
3759 g_assert_cmpstr (printed, ==, "' \\u202c \\U00010220 \\a \\b \\f \\n \\r \\t \\v '");
3760 value = g_variant_parse (NULL, printed, NULL, NULL, NULL);
3761 g_assert_cmpstr (g_variant_get_string (value, NULL), ==, orig);
3762 g_variant_unref (value);
3763 g_free (printed);
3766 #ifndef _MSC_VER
3767 /* inf/nan strings are C99 features which Visual C++ does not support */
3768 /* inf/nan mini test */
3770 const gchar *tests[] = { "inf", "-inf", "nan" };
3771 GVariant *value;
3772 gchar *printed;
3773 gchar *printed_down;
3774 gint i;
3776 for (i = 0; i < G_N_ELEMENTS (tests); i++)
3778 GError *error = NULL;
3779 value = g_variant_parse (NULL, tests[i], NULL, NULL, &error);
3780 printed = g_variant_print (value, FALSE);
3781 /* Canonicalize to lowercase; https://bugzilla.gnome.org/show_bug.cgi?id=704585 */
3782 printed_down = g_ascii_strdown (printed, -1);
3783 g_assert (g_str_has_prefix (printed_down, tests[i]));
3784 g_free (printed);
3785 g_free (printed_down);
3786 g_variant_unref (value);
3789 #endif
3791 g_variant_type_info_assert_no_infos ();
3794 static void
3795 test_parse_failures (void)
3797 const gchar *test[] = {
3798 "[1, 2,", "6:", "expected value",
3799 "", "0:", "expected value",
3800 "(1, 2,", "6:", "expected value",
3801 "<1", "2:", "expected '>'",
3802 "[]", "0-2:", "unable to infer",
3803 "(,", "1:", "expected value",
3804 "[4,'']", "1-2,3-5:", "common type",
3805 "[4, '', 5]", "1-2,4-6:", "common type",
3806 "['', 4, 5]", "1-3,5-6:", "common type",
3807 "[4, 5, '']", "1-2,7-9:", "common type",
3808 "[[4], [], ['']]", "1-4,10-14:", "common type",
3809 "[[], [4], ['']]", "5-8,10-14:", "common type",
3810 "just", "4:", "expected value",
3811 "nothing", "0-7:", "unable to infer",
3812 "just [4, '']", "6-7,9-11:", "common type",
3813 "[[4,'']]", "2-3,4-6:", "common type",
3814 "([4,''],)", "2-3,4-6:", "common type",
3815 "(4)", "2:", "','",
3816 "{}", "0-2:", "unable to infer",
3817 "{[1,2],[3,4]}", "0-13:", "basic types",
3818 "{[1,2]:[3,4]}", "0-13:", "basic types",
3819 "justt", "0-5:", "unknown keyword",
3820 "nothng", "0-6:", "unknown keyword",
3821 "uint33", "0-6:", "unknown keyword",
3822 "@mi just ''", "9-11:", "can not parse as",
3823 "@ai ['']", "5-7:", "can not parse as",
3824 "@(i) ('',)", "6-8:", "can not parse as",
3825 "[[], 5]", "1-3,5-6:", "common type",
3826 "[[5], 5]", "1-4,6-7:", "common type",
3827 "5 5", "2:", "expected end of input",
3828 "[5, [5, '']]", "5-6,8-10:", "common type",
3829 "@i just 5", "3-9:", "can not parse as",
3830 "@i nothing", "3-10:", "can not parse as",
3831 "@i []", "3-5:", "can not parse as",
3832 "@i ()", "3-5:", "can not parse as",
3833 "@ai (4,)", "4-8:", "can not parse as",
3834 "@(i) []", "5-7:", "can not parse as",
3835 "(5 5)", "3:", "expected ','",
3836 "[5 5]", "3:", "expected ',' or ']'",
3837 "(5, 5 5)", "6:", "expected ',' or ')'",
3838 "[5, 5 5]", "6:", "expected ',' or ']'",
3839 "<@i []>", "4-6:", "can not parse as",
3840 "<[5 5]>", "4:", "expected ',' or ']'",
3841 "{[4,''],5}", "2-3,4-6:", "common type",
3842 "{5,[4,'']}", "4-5,6-8:", "common type",
3843 "@i {1,2}", "3-8:", "can not parse as",
3844 "{@i '', 5}", "4-6:", "can not parse as",
3845 "{5, @i ''}", "7-9:", "can not parse as",
3846 "@ai {}", "4-6:", "can not parse as",
3847 "{@i '': 5}", "4-6:", "can not parse as",
3848 "{5: @i ''}", "7-9:", "can not parse as",
3849 "{<4,5}", "3:", "expected '>'",
3850 "{4,<5}", "5:", "expected '>'",
3851 "{4,5,6}", "4:", "expected '}'",
3852 "{5 5}", "3:", "expected ':' or ','",
3853 "{4: 5: 6}", "5:", "expected ',' or '}'",
3854 "{4:5,<6:7}", "7:", "expected '>'",
3855 "{4:5,6:<7}", "9:", "expected '>'",
3856 "{4:5,6 7}", "7:", "expected ':'",
3857 "@o 'foo'", "3-8:", "object path",
3858 "@g 'zzz'", "3-8:", "signature",
3859 "@i true", "3-7:", "can not parse as",
3860 "@z 4", "0-2:", "invalid type",
3861 "@a* []", "0-3:", "definite",
3862 "@ai [3 3]", "7:", "expected ',' or ']'",
3863 "18446744073709551616", "0-20:", "too big for any type",
3864 "-18446744073709551616", "0-21:", "too big for any type",
3865 "byte 256", "5-8:", "out of range for type",
3866 "byte -1", "5-7:", "out of range for type",
3867 "int16 32768", "6-11:", "out of range for type",
3868 "int16 -32769", "6-12:", "out of range for type",
3869 "uint16 -1", "7-9:", "out of range for type",
3870 "uint16 65536", "7-12:", "out of range for type",
3871 "2147483648", "0-10:", "out of range for type",
3872 "-2147483649", "0-11:", "out of range for type",
3873 "uint32 -1", "7-9:", "out of range for type",
3874 "uint32 4294967296", "7-17:", "out of range for type",
3875 "@x 9223372036854775808", "3-22:", "out of range for type",
3876 "@x -9223372036854775809", "3-23:", "out of range for type",
3877 "@t -1", "3-5:", "out of range for type",
3878 "@t 18446744073709551616", "3-23:", "too big for any type",
3879 "handle 2147483648", "7-17:", "out of range for type",
3880 "handle -2147483649", "7-18:", "out of range for type",
3881 "1.798e308", "0-9:", "too big for any type",
3882 "37.5a488", "4-5:", "invalid character",
3883 "0x7ffgf", "5-6:", "invalid character",
3884 "07758", "4-5:", "invalid character",
3885 "123a5", "3-4:", "invalid character",
3886 "@ai 123", "4-7:", "can not parse as",
3887 "'\"\\'", "0-4:", "unterminated string",
3888 "'\"\\'\\", "0-5:", "unterminated string",
3889 "boolean 4", "8-9:", "can not parse as",
3890 "int32 true", "6-10:", "can not parse as",
3891 "[double 5, int32 5]", "1-9,11-18:", "common type",
3892 "string 4", "7-8:", "can not parse as",
3893 "\x0a", "1:", "expected value",
3894 "((", "2:", "expected value",
3896 gint i;
3898 for (i = 0; i < G_N_ELEMENTS (test); i += 3)
3900 GError *error1 = NULL, *error2 = NULL;
3901 GVariant *value;
3903 /* Copy the test string and drop its nul terminator, then use the @limit
3904 * parameter of g_variant_parse() to set the length. This allows valgrind
3905 * to catch 1-byte heap buffer overflows. */
3906 gsize test_len = MAX (strlen (test[i]), 1);
3907 gchar *test_blob = g_malloc0 (test_len); /* no nul terminator */
3909 memcpy (test_blob, test[i], test_len);
3910 value = g_variant_parse (NULL, test_blob, test_blob + test_len, NULL, &error1);
3911 g_assert_null (value);
3913 g_free (test_blob);
3915 if (!strstr (error1->message, test[i+2]))
3916 g_error ("test %d: Can't find '%s' in '%s'", i / 3,
3917 test[i+2], error1->message);
3919 if (!g_str_has_prefix (error1->message, test[i+1]))
3920 g_error ("test %d: Expected location '%s' in '%s'", i / 3,
3921 test[i+1], error1->message);
3923 /* Test again with the nul terminator this time. The behaviour should be
3924 * the same. */
3925 value = g_variant_parse (NULL, test[i], NULL, NULL, &error2);
3926 g_assert_null (value);
3928 g_assert_cmpint (error1->domain, ==, error2->domain);
3929 g_assert_cmpint (error1->code, ==, error2->code);
3930 g_assert_cmpstr (error1->message, ==, error2->message);
3932 g_clear_error (&error1);
3933 g_clear_error (&error2);
3937 static void
3938 test_parse_bad_format_char (void)
3940 g_variant_new_parsed ("%z");
3942 g_assert_not_reached ();
3945 static void
3946 test_parse_bad_format_string (void)
3948 g_variant_new_parsed ("uint32 %i", 2);
3950 g_assert_not_reached ();
3953 static void
3954 test_parse_bad_args (void)
3956 g_variant_new_parsed ("%@i", g_variant_new_uint32 (2));
3958 g_assert_not_reached ();
3961 static void
3962 test_parse_positional (void)
3964 GVariant *value;
3965 check_and_free (g_variant_new_parsed ("[('one', 1), (%s, 2),"
3966 " ('three', %i)]", "two", 3),
3967 "[('one', 1), ('two', 2), ('three', 3)]");
3968 value = g_variant_new_parsed ("[('one', 1), (%s, 2),"
3969 " ('three', %u)]", "two", 3);
3970 g_assert (g_variant_is_of_type (value, G_VARIANT_TYPE ("a(su)")));
3971 check_and_free (value, "[('one', 1), ('two', 2), ('three', 3)]");
3972 check_and_free (g_variant_new_parsed ("{%s:%i}", "one", 1), "{'one': 1}");
3974 if (g_test_undefined ())
3976 do_failed_test ("/gvariant/parse/subprocess/bad-format-char",
3977 "*GVariant format string*");
3979 do_failed_test ("/gvariant/parse/subprocess/bad-format-string",
3980 "*can not parse as*");
3982 do_failed_test ("/gvariant/parse/subprocess/bad-args",
3983 "*expected GVariant of type 'i'*");
3987 static void
3988 test_floating (void)
3990 GVariant *value;
3992 value = g_variant_new_int32 (42);
3993 g_assert (g_variant_is_floating (value));
3994 g_variant_ref_sink (value);
3995 g_assert (!g_variant_is_floating (value));
3996 g_variant_unref (value);
3999 static void
4000 test_bytestring (void)
4002 const gchar *test_string = "foo,bar,baz,quux,\xffoooo";
4003 GVariant *value;
4004 gchar **strv;
4005 gchar *str;
4006 const gchar *const_str;
4007 GVariant *untrusted_empty;
4009 strv = g_strsplit (test_string, ",", 0);
4011 value = g_variant_new_bytestring_array ((const gchar **) strv, -1);
4012 g_assert (g_variant_is_floating (value));
4013 g_strfreev (strv);
4015 str = g_variant_print (value, FALSE);
4016 g_variant_unref (value);
4018 value = g_variant_parse (NULL, str, NULL, NULL, NULL);
4019 g_free (str);
4021 strv = g_variant_dup_bytestring_array (value, NULL);
4022 g_variant_unref (value);
4024 str = g_strjoinv (",", strv);
4025 g_strfreev (strv);
4027 g_assert_cmpstr (str, ==, test_string);
4028 g_free (str);
4030 strv = g_strsplit (test_string, ",", 0);
4031 value = g_variant_new ("(^aay^a&ay^ay^&ay)",
4032 strv, strv, strv[0], strv[0]);
4033 g_strfreev (strv);
4035 g_variant_get_child (value, 0, "^a&ay", &strv);
4036 str = g_strjoinv (",", strv);
4037 g_free (strv);
4038 g_assert_cmpstr (str, ==, test_string);
4039 g_free (str);
4041 g_variant_get_child (value, 0, "^aay", &strv);
4042 str = g_strjoinv (",", strv);
4043 g_strfreev (strv);
4044 g_assert_cmpstr (str, ==, test_string);
4045 g_free (str);
4047 g_variant_get_child (value, 1, "^a&ay", &strv);
4048 str = g_strjoinv (",", strv);
4049 g_free (strv);
4050 g_assert_cmpstr (str, ==, test_string);
4051 g_free (str);
4053 g_variant_get_child (value, 1, "^aay", &strv);
4054 str = g_strjoinv (",", strv);
4055 g_strfreev (strv);
4056 g_assert_cmpstr (str, ==, test_string);
4057 g_free (str);
4059 g_variant_get_child (value, 2, "^ay", &str);
4060 g_assert_cmpstr (str, ==, "foo");
4061 g_free (str);
4063 g_variant_get_child (value, 2, "^&ay", &str);
4064 g_assert_cmpstr (str, ==, "foo");
4066 g_variant_get_child (value, 3, "^ay", &str);
4067 g_assert_cmpstr (str, ==, "foo");
4068 g_free (str);
4070 g_variant_get_child (value, 3, "^&ay", &str);
4071 g_assert_cmpstr (str, ==, "foo");
4072 g_variant_unref (value);
4074 untrusted_empty = g_variant_new_from_data (G_VARIANT_TYPE ("ay"), NULL, 0, FALSE, NULL, NULL);
4075 value = g_variant_get_normal_form (untrusted_empty);
4076 const_str = g_variant_get_bytestring (value);
4077 (void) const_str;
4078 g_variant_unref (value);
4079 g_variant_unref (untrusted_empty);
4082 static void
4083 test_lookup_value (void)
4085 struct {
4086 const gchar *dict, *key, *value;
4087 } cases[] = {
4088 { "@a{ss} {'x': 'y'}", "x", "'y'" },
4089 { "@a{ss} {'x': 'y'}", "y" },
4090 { "@a{os} {'/x': 'y'}", "/x", "'y'" },
4091 { "@a{os} {'/x': 'y'}", "/y" },
4092 { "@a{sv} {'x': <'y'>}", "x", "'y'" },
4093 { "@a{sv} {'x': <5>}", "x", "5" },
4094 { "@a{sv} {'x': <'y'>}", "y" }
4096 gint i;
4098 for (i = 0; i < G_N_ELEMENTS (cases); i++)
4100 GVariant *dictionary;
4101 GVariant *value;
4102 gchar *p;
4104 dictionary = g_variant_parse (NULL, cases[i].dict, NULL, NULL, NULL);
4105 value = g_variant_lookup_value (dictionary, cases[i].key, NULL);
4106 g_variant_unref (dictionary);
4108 if (value == NULL && cases[i].value == NULL)
4109 continue;
4111 g_assert (value && cases[i].value);
4112 p = g_variant_print (value, FALSE);
4113 g_assert_cmpstr (cases[i].value, ==, p);
4114 g_variant_unref (value);
4115 g_free (p);
4119 static void
4120 test_lookup (void)
4122 const gchar *str;
4123 GVariant *dict;
4124 gboolean ok;
4125 gint num;
4127 dict = g_variant_parse (NULL,
4128 "{'a': <5>, 'b': <'c'>}",
4129 NULL, NULL, NULL);
4131 ok = g_variant_lookup (dict, "a", "i", &num);
4132 g_assert (ok);
4133 g_assert_cmpint (num, ==, 5);
4135 ok = g_variant_lookup (dict, "a", "&s", &str);
4136 g_assert (!ok);
4138 ok = g_variant_lookup (dict, "q", "&s", &str);
4139 g_assert (!ok);
4141 ok = g_variant_lookup (dict, "b", "i", &num);
4142 g_assert (!ok);
4144 ok = g_variant_lookup (dict, "b", "&s", &str);
4145 g_assert (ok);
4146 g_assert_cmpstr (str, ==, "c");
4148 ok = g_variant_lookup (dict, "q", "&s", &str);
4149 g_assert (!ok);
4151 g_variant_unref (dict);
4154 static GVariant *
4155 untrusted (GVariant *a)
4157 GVariant *b;
4158 const GVariantType *type;
4159 GBytes *bytes;
4161 type = g_variant_get_type (a);
4162 bytes = g_variant_get_data_as_bytes (a);
4163 b = g_variant_new_from_bytes (type, bytes, FALSE);
4164 g_bytes_unref (bytes);
4165 g_variant_unref (a);
4167 return b;
4170 static void
4171 test_compare (void)
4173 GVariant *a;
4174 GVariant *b;
4176 a = untrusted (g_variant_new_byte (5));
4177 b = g_variant_new_byte (6);
4178 g_assert (g_variant_compare (a, b) < 0);
4179 g_variant_unref (a);
4180 g_variant_unref (b);
4181 a = untrusted (g_variant_new_int16 (G_MININT16));
4182 b = g_variant_new_int16 (G_MAXINT16);
4183 g_assert (g_variant_compare (a, b) < 0);
4184 g_variant_unref (a);
4185 g_variant_unref (b);
4186 a = untrusted (g_variant_new_uint16 (0));
4187 b = g_variant_new_uint16 (G_MAXUINT16);
4188 g_assert (g_variant_compare (a, b) < 0);
4189 g_variant_unref (a);
4190 g_variant_unref (b);
4191 a = untrusted (g_variant_new_int32 (G_MININT32));
4192 b = g_variant_new_int32 (G_MAXINT32);
4193 g_assert (g_variant_compare (a, b) < 0);
4194 g_variant_unref (a);
4195 g_variant_unref (b);
4196 a = untrusted (g_variant_new_uint32 (0));
4197 b = g_variant_new_uint32 (G_MAXUINT32);
4198 g_assert (g_variant_compare (a, b) < 0);
4199 g_variant_unref (a);
4200 g_variant_unref (b);
4201 a = untrusted (g_variant_new_int64 (G_MININT64));
4202 b = g_variant_new_int64 (G_MAXINT64);
4203 g_assert (g_variant_compare (a, b) < 0);
4204 g_variant_unref (a);
4205 g_variant_unref (b);
4206 a = untrusted (g_variant_new_uint64 (0));
4207 b = g_variant_new_uint64 (G_MAXUINT64);
4208 g_assert (g_variant_compare (a, b) < 0);
4209 g_variant_unref (a);
4210 g_variant_unref (b);
4211 a = untrusted (g_variant_new_double (G_MINDOUBLE));
4212 b = g_variant_new_double (G_MAXDOUBLE);
4213 g_assert (g_variant_compare (a, b) < 0);
4214 g_variant_unref (a);
4215 g_variant_unref (b);
4216 a = untrusted (g_variant_new_string ("abc"));
4217 b = g_variant_new_string ("abd");
4218 g_assert (g_variant_compare (a, b) < 0);
4219 g_variant_unref (a);
4220 g_variant_unref (b);
4221 a = untrusted (g_variant_new_object_path ("/abc"));
4222 b = g_variant_new_object_path ("/abd");
4223 g_assert (g_variant_compare (a, b) < 0);
4224 g_variant_unref (a);
4225 g_variant_unref (b);
4226 a = untrusted (g_variant_new_signature ("g"));
4227 b = g_variant_new_signature ("o");
4228 g_assert (g_variant_compare (a, b) < 0);
4229 g_variant_unref (a);
4230 g_variant_unref (b);
4231 a = untrusted (g_variant_new_boolean (FALSE));
4232 b = g_variant_new_boolean (TRUE);
4233 g_assert (g_variant_compare (a, b) < 0);
4234 g_variant_unref (a);
4235 g_variant_unref (b);
4238 static void
4239 test_equal (void)
4241 GVariant *a;
4242 GVariant *b;
4244 a = untrusted (g_variant_new_byte (5));
4245 b = g_variant_get_normal_form (a);
4246 g_assert (g_variant_equal (a, b));
4247 g_variant_unref (a);
4248 g_variant_unref (b);
4249 a = untrusted (g_variant_new_int16 (G_MININT16));
4250 b = g_variant_get_normal_form (a);
4251 g_assert (g_variant_equal (a, b));
4252 g_variant_unref (a);
4253 g_variant_unref (b);
4254 a = untrusted (g_variant_new_uint16 (0));
4255 b = g_variant_get_normal_form (a);
4256 g_assert (g_variant_equal (a, b));
4257 g_variant_unref (a);
4258 g_variant_unref (b);
4259 a = untrusted (g_variant_new_int32 (G_MININT32));
4260 b = g_variant_get_normal_form (a);
4261 g_assert (g_variant_equal (a, b));
4262 g_variant_unref (a);
4263 g_variant_unref (b);
4264 a = untrusted (g_variant_new_uint32 (0));
4265 b = g_variant_get_normal_form (a);
4266 g_assert (g_variant_equal (a, b));
4267 g_variant_unref (a);
4268 g_variant_unref (b);
4269 a = untrusted (g_variant_new_int64 (G_MININT64));
4270 b = g_variant_get_normal_form (a);
4271 g_assert (g_variant_equal (a, b));
4272 g_variant_unref (a);
4273 g_variant_unref (b);
4274 a = untrusted (g_variant_new_uint64 (0));
4275 b = g_variant_get_normal_form (a);
4276 g_assert (g_variant_equal (a, b));
4277 g_variant_unref (a);
4278 g_variant_unref (b);
4279 a = untrusted (g_variant_new_double (G_MINDOUBLE));
4280 b = g_variant_get_normal_form (a);
4281 g_assert (g_variant_equal (a, b));
4282 g_variant_unref (a);
4283 g_variant_unref (b);
4284 a = untrusted (g_variant_new_string ("abc"));
4285 g_assert (g_variant_equal (a, a));
4286 b = g_variant_get_normal_form (a);
4287 g_assert (g_variant_equal (a, b));
4288 g_variant_unref (a);
4289 g_variant_unref (b);
4290 a = untrusted (g_variant_new_object_path ("/abc"));
4291 g_assert (g_variant_equal (a, a));
4292 b = g_variant_get_normal_form (a);
4293 a = untrusted (a);
4294 g_assert (g_variant_equal (a, b));
4295 g_variant_unref (a);
4296 g_variant_unref (b);
4297 a = untrusted (g_variant_new_signature ("g"));
4298 g_assert (g_variant_equal (a, a));
4299 b = g_variant_get_normal_form (a);
4300 a = untrusted (a);
4301 g_assert (g_variant_equal (a, b));
4302 g_variant_unref (a);
4303 g_variant_unref (b);
4304 a = untrusted (g_variant_new_boolean (FALSE));
4305 b = g_variant_get_normal_form (a);
4306 g_assert (g_variant_equal (a, b));
4307 g_variant_unref (a);
4308 g_variant_unref (b);
4311 static void
4312 test_fixed_array (void)
4314 GVariant *a;
4315 gint32 values[5];
4316 const gint32 *elts;
4317 gsize n_elts;
4318 gint i;
4320 n_elts = 0;
4321 a = g_variant_new_parsed ("[1,2,3,4,5]");
4322 elts = g_variant_get_fixed_array (a, &n_elts, sizeof (gint32));
4323 g_assert (n_elts == 5);
4324 for (i = 0; i < 5; i++)
4325 g_assert_cmpint (elts[i], ==, i + 1);
4326 g_variant_unref (a);
4328 n_elts = 0;
4329 for (i = 0; i < 5; i++)
4330 values[i] = i + 1;
4331 a = g_variant_new_fixed_array (G_VARIANT_TYPE_INT32, values,
4332 G_N_ELEMENTS (values), sizeof (values[0]));
4333 g_assert_cmpstr (g_variant_get_type_string (a), ==, "ai");
4334 elts = g_variant_get_fixed_array (a, &n_elts, sizeof (gint32));
4335 g_assert (n_elts == 5);
4336 for (i = 0; i < 5; i++)
4337 g_assert_cmpint (elts[i], ==, i + 1);
4338 g_variant_unref (a);
4341 static void
4342 test_check_format_string (void)
4344 GVariant *value;
4346 value = g_variant_new ("(sas)", "foo", NULL);
4347 g_variant_ref_sink (value);
4349 g_assert (g_variant_check_format_string (value, "(s*)", TRUE));
4350 g_assert (g_variant_check_format_string (value, "(s*)", FALSE));
4351 g_assert (!g_variant_check_format_string (value, "(u*)", TRUE));
4352 g_assert (!g_variant_check_format_string (value, "(u*)", FALSE));
4354 g_assert (g_variant_check_format_string (value, "(&s*)", FALSE));
4355 g_test_expect_message ("GLib", G_LOG_LEVEL_CRITICAL, "*contains a '&' character*");
4356 g_assert (!g_variant_check_format_string (value, "(&s*)", TRUE));
4357 g_test_assert_expected_messages ();
4359 g_assert (g_variant_check_format_string (value, "(s^as)", TRUE));
4360 g_assert (g_variant_check_format_string (value, "(s^as)", FALSE));
4362 g_test_expect_message ("GLib", G_LOG_LEVEL_CRITICAL, "*contains a '&' character*");
4363 g_assert (!g_variant_check_format_string (value, "(s^a&s)", TRUE));
4364 g_test_assert_expected_messages ();
4365 g_assert (g_variant_check_format_string (value, "(s^a&s)", FALSE));
4367 g_variant_unref (value);
4369 /* Do it again with a type that will let us put a '&' after a '^' */
4370 value = g_variant_new ("(say)", "foo", NULL);
4371 g_variant_ref_sink (value);
4373 g_assert (g_variant_check_format_string (value, "(s*)", TRUE));
4374 g_assert (g_variant_check_format_string (value, "(s*)", FALSE));
4375 g_assert (!g_variant_check_format_string (value, "(u*)", TRUE));
4376 g_assert (!g_variant_check_format_string (value, "(u*)", FALSE));
4378 g_assert (g_variant_check_format_string (value, "(&s*)", FALSE));
4379 g_test_expect_message ("GLib", G_LOG_LEVEL_CRITICAL, "*contains a '&' character*");
4380 g_assert (!g_variant_check_format_string (value, "(&s*)", TRUE));
4381 g_test_assert_expected_messages ();
4383 g_assert (g_variant_check_format_string (value, "(s^ay)", TRUE));
4384 g_assert (g_variant_check_format_string (value, "(s^ay)", FALSE));
4386 g_test_expect_message ("GLib", G_LOG_LEVEL_CRITICAL, "*contains a '&' character*");
4387 g_assert (!g_variant_check_format_string (value, "(s^&ay)", TRUE));
4388 g_test_assert_expected_messages ();
4389 g_assert (g_variant_check_format_string (value, "(s^&ay)", FALSE));
4391 g_assert (g_variant_check_format_string (value, "r", FALSE));
4392 g_assert (g_variant_check_format_string (value, "(?a?)", FALSE));
4394 g_variant_unref (value);
4397 static void
4398 verify_gvariant_checksum (const gchar *sha256,
4399 GVariant *v)
4402 gchar *checksum;
4403 checksum = g_compute_checksum_for_data (G_CHECKSUM_SHA256,
4404 g_variant_get_data (v),
4405 g_variant_get_size (v));
4406 g_assert_cmpstr (sha256, ==, checksum);
4407 g_free (checksum);
4410 static void
4411 verify_gvariant_checksum_va (const gchar *sha256,
4412 const gchar *fmt,
4413 ...)
4415 va_list args;
4416 GVariant *v;
4418 va_start (args, fmt);
4420 v = g_variant_new_va (fmt, NULL, &args);
4421 g_variant_ref_sink (v);
4422 #if G_BYTE_ORDER == G_BIG_ENDIAN
4424 GVariant *byteswapped = g_variant_byteswap (v);
4425 g_variant_unref (v);
4426 v = byteswapped;
4428 #endif
4430 va_end (args);
4432 verify_gvariant_checksum (sha256, v);
4434 g_variant_unref (v);
4437 static void
4438 test_checksum_basic (void)
4440 verify_gvariant_checksum_va ("e8a4b2ee7ede79a3afb332b5b6cc3d952a65fd8cffb897f5d18016577c33d7cc",
4441 "u", 42);
4442 verify_gvariant_checksum_va ("c53e363c33b00cfce298229ee83856b8a98c2e6126cab13f65899f62473b0df5",
4443 "s", "moocow");
4444 verify_gvariant_checksum_va ("2b4c342f5433ebe591a1da77e013d1b72475562d48578dca8b84bac6651c3cb9",
4445 "y", 9);
4446 verify_gvariant_checksum_va ("12a3ae445661ce5dee78d0650d33362dec29c4f82af05e7e57fb595bbbacf0ca",
4447 "t", G_MAXUINT64);
4448 verify_gvariant_checksum_va ("e25a59b24440eb6c833aa79c93b9840e6eab6966add0dacf31df7e9e7000f5b3",
4449 "d", 3.14159);
4450 verify_gvariant_checksum_va ("4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a",
4451 "b", TRUE);
4452 verify_gvariant_checksum_va ("ca2fd00fa001190744c15c317643ab092e7048ce086a243e2be9437c898de1bb",
4453 "q", G_MAXUINT16);
4456 static void
4457 test_checksum_nested (void)
4459 static const char* const strv[] = {"foo", "bar", "baz", NULL};
4461 verify_gvariant_checksum_va ("31fbc92f08fddaca716188fe4b5d44ae122fc6306fd3c6925af53cfa47ea596d",
4462 "(uu)", 41, 43);
4463 verify_gvariant_checksum_va ("01759d683cead856d1d386d59af0578841698a424a265345ad5413122f220de8",
4464 "(su)", "moocow", 79);
4465 verify_gvariant_checksum_va ("52b3ae95f19b3e642ea1d01185aea14a09004c1d1712672644427403a8a0afe6",
4466 "(qyst)", G_MAXUINT16, 9, "moocow", G_MAXUINT64);
4467 verify_gvariant_checksum_va ("6fc6f4524161c3ae0d316812d7088e3fcd372023edaea2d7821093be40ae1060",
4468 "(@ay)", g_variant_new_bytestring ("\xFF\xFF\xFF"));
4469 verify_gvariant_checksum_va ("572aca386e1a983dd23bb6eb6e3dfa72eef9ca7c7744581aa800e18d7d9d0b0b",
4470 "(^as)", strv);
4471 verify_gvariant_checksum_va ("4bddf6174c791bb44fc6a4106573031690064df34b741033a0122ed8dc05bcf3",
4472 "(yvu)", 254, g_variant_new ("(^as)", strv), 42);
4475 static void
4476 test_gbytes (void)
4478 GVariant *a;
4479 GVariant *tuple;
4480 GBytes *bytes;
4481 GBytes *bytes2;
4482 const guint8 values[5] = { 1, 2, 3, 4, 5 };
4483 const guint8 *elts;
4484 gsize n_elts;
4485 gint i;
4487 bytes = g_bytes_new (&values, 5);
4488 a = g_variant_new_from_bytes (G_VARIANT_TYPE_BYTESTRING, bytes, TRUE);
4489 g_bytes_unref (bytes);
4490 n_elts = 0;
4491 elts = g_variant_get_fixed_array (a, &n_elts, sizeof (guint8));
4492 g_assert (n_elts == 5);
4493 for (i = 0; i < 5; i++)
4494 g_assert_cmpint (elts[i], ==, i + 1);
4496 bytes2 = g_variant_get_data_as_bytes (a);
4497 g_variant_unref (a);
4499 bytes = g_bytes_new (&values, 5);
4500 g_assert (g_bytes_equal (bytes, bytes2));
4501 g_bytes_unref (bytes);
4502 g_bytes_unref (bytes2);
4504 tuple = g_variant_new_parsed ("['foo', 'bar']");
4505 bytes = g_variant_get_data_as_bytes (tuple); /* force serialisation */
4506 a = g_variant_get_child_value (tuple, 1);
4507 bytes2 = g_variant_get_data_as_bytes (a);
4508 g_assert (!g_bytes_equal (bytes, bytes2));
4510 g_bytes_unref (bytes);
4511 g_bytes_unref (bytes2);
4512 g_variant_unref (a);
4513 g_variant_unref (tuple);
4516 typedef struct {
4517 const GVariantType *type;
4518 const gchar *in;
4519 const gchar *out;
4520 } ContextTest;
4522 static void
4523 test_print_context (void)
4525 ContextTest tests[] = {
4526 { NULL, "(1, 2, 3, 'abc", " ^^^^" },
4527 { NULL, "[1, 2, 3, 'str']", " ^ ^^^^^" },
4528 { G_VARIANT_TYPE_UINT16, "{ 'abc':'def' }", " ^^^^^^^^^^^^^^^" },
4529 { NULL, "<5", " ^" },
4530 { NULL, "'ab\\ux'", " ^^^^^^^" },
4531 { NULL, "'ab\\U00efx'", " ^^^^^^^^^^^" }
4533 GVariant *v;
4534 gchar *s;
4535 gint i;
4536 GError *error = NULL;
4538 for (i = 0; i < G_N_ELEMENTS (tests); i++)
4540 v = g_variant_parse (tests[i].type, tests[i].in, NULL, NULL, &error);
4541 g_assert_null (v);
4542 s = g_variant_parse_error_print_context (error, tests[i].in);
4543 g_assert (strstr (s, tests[i].out) != NULL);
4544 g_free (s);
4545 g_clear_error (&error);
4549 static void
4550 test_error_quark (void)
4552 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
4553 g_assert (g_variant_parser_get_error_quark () == g_variant_parse_error_quark ());
4554 G_GNUC_END_IGNORE_DEPRECATIONS
4557 static void
4558 test_stack_builder_init (void)
4560 GVariantBuilder builder = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE_BYTESTRING);
4561 GVariant *variant;
4563 g_variant_builder_add_value (&builder, g_variant_new_byte ('g'));
4564 g_variant_builder_add_value (&builder, g_variant_new_byte ('l'));
4565 g_variant_builder_add_value (&builder, g_variant_new_byte ('i'));
4566 g_variant_builder_add_value (&builder, g_variant_new_byte ('b'));
4567 g_variant_builder_add_value (&builder, g_variant_new_byte ('\0'));
4569 variant = g_variant_ref_sink (g_variant_builder_end (&builder));
4570 g_assert_nonnull (variant);
4571 g_assert (g_variant_type_equal (g_variant_get_type (variant),
4572 G_VARIANT_TYPE_BYTESTRING));
4573 g_assert_cmpuint (g_variant_n_children (variant), ==, 5);
4574 g_assert_cmpstr (g_variant_get_bytestring (variant), ==, "glib");
4575 g_variant_unref (variant);
4578 static GVariant *
4579 get_asv (void)
4581 GVariantBuilder builder = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE_VARDICT);
4583 g_variant_builder_add (&builder, "{s@v}", "foo", g_variant_new_variant (g_variant_new_string ("FOO")));
4584 g_variant_builder_add (&builder, "{s@v}", "bar", g_variant_new_variant (g_variant_new_string ("BAR")));
4586 return g_variant_ref_sink (g_variant_builder_end (&builder));
4589 static void
4590 test_stack_dict_init (void)
4592 GVariant *asv = get_asv ();
4593 GVariantDict dict = G_VARIANT_DICT_INIT (asv);
4594 GVariant *variant;
4595 GVariantIter iter;
4596 gchar *key;
4597 GVariant *value;
4599 g_variant_dict_insert_value (&dict, "baz", g_variant_new_string ("BAZ"));
4600 g_variant_dict_insert_value (&dict, "quux", g_variant_new_string ("QUUX"));
4602 variant = g_variant_ref_sink (g_variant_dict_end (&dict));
4603 g_assert_nonnull (variant);
4604 g_assert (g_variant_type_equal (g_variant_get_type (variant),
4605 G_VARIANT_TYPE_VARDICT));
4606 g_assert_cmpuint (g_variant_n_children (variant), ==, 4);
4608 g_variant_iter_init (&iter, variant);
4609 while (g_variant_iter_next (&iter, "{sv}", &key, &value))
4611 gchar *strup = g_ascii_strup (key, -1);
4613 g_assert_cmpstr (strup, ==, g_variant_get_string (value, NULL));
4614 g_free (key);
4615 g_free (strup);
4616 g_variant_unref (value);
4619 g_variant_unref (asv);
4620 g_variant_unref (variant);
4624 main (int argc, char **argv)
4626 gint i;
4628 g_test_init (&argc, &argv, NULL);
4630 g_test_add_func ("/gvariant/type", test_gvarianttype);
4631 g_test_add_func ("/gvariant/typeinfo", test_gvarianttypeinfo);
4632 g_test_add_func ("/gvariant/serialiser/maybe", test_maybes);
4633 g_test_add_func ("/gvariant/serialiser/array", test_arrays);
4634 g_test_add_func ("/gvariant/serialiser/tuple", test_tuples);
4635 g_test_add_func ("/gvariant/serialiser/variant", test_variants);
4636 g_test_add_func ("/gvariant/serialiser/strings", test_strings);
4637 g_test_add_func ("/gvariant/serialiser/byteswap", test_byteswaps);
4639 for (i = 1; i <= 20; i += 4)
4641 char *testname;
4643 testname = g_strdup_printf ("/gvariant/serialiser/fuzz/%d%%", i);
4644 g_test_add_data_func (testname, GINT_TO_POINTER (i),
4645 (gpointer) test_fuzzes);
4646 g_free (testname);
4649 g_test_add_func ("/gvariant/string", test_string);
4650 g_test_add_func ("/gvariant/utf8", test_utf8);
4651 g_test_add_func ("/gvariant/containers", test_containers);
4652 g_test_add_func ("/gvariant/format-strings", test_format_strings);
4653 g_test_add_func ("/gvariant/invalid-varargs", test_invalid_varargs);
4654 g_test_add_func ("/gvariant/varargs", test_varargs);
4655 g_test_add_func ("/gvariant/varargs/subprocess/empty-array", test_varargs_empty_array);
4656 g_test_add_func ("/gvariant/valist", test_valist);
4657 g_test_add_func ("/gvariant/builder-memory", test_builder_memory);
4658 g_test_add_func ("/gvariant/hashing", test_hashing);
4659 g_test_add_func ("/gvariant/byteswap", test_gv_byteswap);
4660 g_test_add_func ("/gvariant/parser", test_parses);
4661 g_test_add_func ("/gvariant/parse-failures", test_parse_failures);
4662 g_test_add_func ("/gvariant/parse-positional", test_parse_positional);
4663 g_test_add_func ("/gvariant/parse/subprocess/bad-format-char", test_parse_bad_format_char);
4664 g_test_add_func ("/gvariant/parse/subprocess/bad-format-string", test_parse_bad_format_string);
4665 g_test_add_func ("/gvariant/parse/subprocess/bad-args", test_parse_bad_args);
4666 g_test_add_func ("/gvariant/floating", test_floating);
4667 g_test_add_func ("/gvariant/bytestring", test_bytestring);
4668 g_test_add_func ("/gvariant/lookup-value", test_lookup_value);
4669 g_test_add_func ("/gvariant/lookup", test_lookup);
4670 g_test_add_func ("/gvariant/compare", test_compare);
4671 g_test_add_func ("/gvariant/equal", test_equal);
4672 g_test_add_func ("/gvariant/fixed-array", test_fixed_array);
4673 g_test_add_func ("/gvariant/check-format-string", test_check_format_string);
4675 g_test_add_func ("/gvariant/checksum-basic", test_checksum_basic);
4676 g_test_add_func ("/gvariant/checksum-nested", test_checksum_nested);
4678 g_test_add_func ("/gvariant/gbytes", test_gbytes);
4679 g_test_add_func ("/gvariant/print-context", test_print_context);
4680 g_test_add_func ("/gvariant/error-quark", test_error_quark);
4682 g_test_add_func ("/gvariant/stack-builder-init", test_stack_builder_init);
4683 g_test_add_func ("/gvariant/stack-dict-init", test_stack_dict_init);
4684 return g_test_run ();