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 of the licence, or (at your option) any later version.
9 * See the included COPYING file for more information.
11 * Author: Ryan Lortie <desrt@desrt.ca>
16 #include <glib/gvariant-internal.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)
39 randomly (gdouble prob)
41 return g_test_rand_double_range (0, 1) < prob;
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
53 append_type_string (GString *string,
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);
67 return g_variant_type_copy (G_VARIANT_TYPE_BOOLEAN);
69 return g_variant_type_copy (G_VARIANT_TYPE_BYTE);
71 return g_variant_type_copy (G_VARIANT_TYPE_INT16);
73 return g_variant_type_copy (G_VARIANT_TYPE_UINT16);
75 return g_variant_type_copy (G_VARIANT_TYPE_INT32);
77 return g_variant_type_copy (G_VARIANT_TYPE_UINT32);
79 return g_variant_type_copy (G_VARIANT_TYPE_INT64);
81 return g_variant_type_copy (G_VARIANT_TYPE_UINT64);
83 return g_variant_type_copy (G_VARIANT_TYPE_HANDLE);
85 return g_variant_type_copy (G_VARIANT_TYPE_DOUBLE);
87 return g_variant_type_copy (G_VARIANT_TYPE_STRING);
89 return g_variant_type_copy (G_VARIANT_TYPE_OBJECT_PATH);
91 return g_variant_type_copy (G_VARIANT_TYPE_SIGNATURE);
93 return g_variant_type_copy (G_VARIANT_TYPE_BASIC);
95 g_assert_not_reached ();
100 GVariantType *result;
102 switch (g_test_rand_int_range (0, definite ? 5 : 7))
106 GVariantType *element;
108 g_string_append_c (string, 'a');
109 g_string_append (description, "a of ");
110 element = append_type_string (string, description,
112 result = g_variant_type_new_array (element);
113 g_variant_type_free (element);
116 g_assert (g_variant_type_is_array (result));
121 GVariantType *element;
123 g_string_append_c (string, 'm');
124 g_string_append (description, "m of ");
125 element = append_type_string (string, description,
127 result = g_variant_type_new_maybe (element);
128 g_variant_type_free (element);
131 g_assert (g_variant_type_is_maybe (result));
135 result = append_tuple_type_string (string, description,
138 g_assert (g_variant_type_is_tuple (result));
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));
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));
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));
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));
182 g_assert_not_reached ();
189 static GVariantType *
190 append_tuple_type_string (GString *string,
191 GString *description,
195 GVariantType *result, *other_result;
196 GVariantType **types;
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);
211 g_string_append (description, ", ");
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]);
230 /* given a valid type string, make it invalid */
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 */
248 new = g_strdup (type_string);
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;
268 while (np--) pp = strchr (pp + 1, p);
269 while (nb--) bp = strchr (bp + 1, b);
272 g_assert (*bp == b && *pp == p);
279 if ((have_parens || have_braces) && randomly (0.3))
281 /* drop a paren/brace */
288 if (randomly (0.5)) p = '('; else p = ')';
290 if (randomly (0.5)) p = '{'; else p = '}';
292 new = g_strdup (type_string);
296 while ((pp = strchr (pp + 1, p))) np++;
297 np = g_test_rand_int_range (0, np) + 1;
299 while (np--) pp = strchr (pp + 1, p);
311 /* else, perform a random mutation at a random point */
319 /* insert a paren/brace */
321 if (randomly (0.5)) p = '('; else p = ')';
323 if (randomly (0.5)) p = '{'; else p = '}';
325 else if (randomly (0.5))
328 p = INVALIDS[g_test_rand_int_range (0, N_INVALIDS)];
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);
342 memcpy (new + n + 1, type_string + n, length - n);
343 new[length + 1] = '\0';
349 /* describe a type using the same language as is generated
350 * while generating the type with append_type_string
353 describe_type (const GVariantType *type)
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);
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);
373 else if (g_variant_type_is_tuple (type))
375 if (!g_variant_type_equal (type, G_VARIANT_TYPE_TUPLE))
377 const GVariantType *sub;
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);
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);
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);
422 else if (g_variant_type_equal (type, G_VARIANT_TYPE_VARIANT))
424 result = g_strdup ("V");
427 g_assert_not_reached ();
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");
462 g_assert_not_reached ();
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 ("?");
475 g_assert_not_reached ();
482 /* given a type string, replace one of the indefinite type characters in
483 * it with a matching type (possibly the same type).
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;
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);
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);
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.
552 subtype_check (const gchar *type_string,
553 struct typestack *parent_ts)
555 struct typestack ts, *node;
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));
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);
589 test_gvarianttype (void)
593 for (i = 0; i < 2000; i++)
595 GString *type_string, *description;
596 GVariantType *type, *other_type;
597 const GVariantType *ctype;
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);
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);
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));
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.
671 calculate_type_info (const GVariantType *type,
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);
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;
697 sub = g_variant_type_first (type);
703 calculate_type_info (sub, &this_fs, &this_al);
705 al = MAX (al, this_al);
715 size = ALIGNED (size, this_al);
719 while ((sub = g_variant_type_next (sub)));
721 size = ALIGNED (size, al);
742 if (g_variant_type_equal (type, G_VARIANT_TYPE_BOOLEAN) ||
743 g_variant_type_equal (type, G_VARIANT_TYPE_BYTE))
748 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT16) ||
749 g_variant_type_equal (type, G_VARIANT_TYPE_UINT16))
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))
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))
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))
774 else if (g_variant_type_equal (type, G_VARIANT_TYPE_VARIANT))
780 g_assert_not_reached ();
790 /* same as the describe_type() function above, but iterates over
791 * typeinfo instead of types.
794 describe_info (GVariantTypeInfo *info)
798 switch (g_variant_type_info_get_type_char (info))
800 case G_VARIANT_TYPE_INFO_CHAR_MAYBE:
804 element = describe_info (g_variant_type_info_element (info));
805 result = g_strdup_printf ("m of %s", element);
810 case G_VARIANT_TYPE_INFO_CHAR_ARRAY:
814 element = describe_info (g_variant_type_info_element (info));
815 result = g_strdup_printf ("a of %s", element);
820 case G_VARIANT_TYPE_INFO_CHAR_TUPLE:
822 const gchar *sep = "";
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;
835 g_string_append (string, sep);
838 minfo = g_variant_type_info_member_info (info, i);
839 subtype = describe_info (minfo->type_info);
840 g_string_append (string, subtype);
844 g_string_append_c (string, ']');
846 result = g_string_free (string, FALSE);
850 case G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY:
852 const GVariantMemberInfo *keyinfo, *valueinfo;
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);
866 case G_VARIANT_TYPE_INFO_CHAR_VARIANT:
867 result = g_strdup ("V");
871 result = g_strdup (g_variant_type_info_get_type_string (info));
872 g_assert_cmpint (strlen (result), ==, 1);
879 /* check that the O(1) method of calculating offsets meshes with the
880 * results of simple iteration.
883 check_offsets (GVariantTypeInfo *info,
884 const GVariantType *type)
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;
904 subtype = g_variant_type_first (type);
905 last_offset_index = -1;
909 /* go through the tuple, keeping track of our position */
910 for (i = 0; i < length; i++)
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
924 const GVariantMemberInfo *member;
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 */
936 /* did we reach the same spot? */
937 g_assert_cmpint (start, ==, position);
942 /* fixed size. add that size. */
943 position += fixed_size;
947 /* variable size. do the flavouring. */
948 while ((position & 0x7) != flavour)
951 /* and store the offset, just like it would be in the
954 last_offset = position;
959 subtype = g_variant_type_next (subtype);
962 /* make sure we used up exactly all the types */
963 g_assert (subtype == NULL);
968 test_gvarianttypeinfo (void)
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;
981 type_string = g_string_new (NULL);
982 description = g_string_new (NULL);
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), ==,
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;
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);
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
1056 random_type_string (void)
1058 const guchar base_types[] = "ynix";
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];
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);
1080 /* construct a variable-sized type */
1082 char type_string[2] = { 'a', base_type };
1084 return g_strndup (type_string, 2);
1090 GVariantTypeInfo *type_info;
1093 gboolean is_fixed_sized;
1097 #define INSTANCE_MAGIC 1287582829
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));
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,
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;
1134 random_instance_free (RandomInstance *instance)
1136 g_variant_type_info_unref (instance->type_info);
1137 g_slice_free (RandomInstance, instance);
1141 append_instance_size (RandomInstance *instance,
1144 *offset += (-*offset) & instance->alignment;
1145 *offset += instance->size;
1149 random_instance_write (RandomInstance *instance,
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);
1164 append_instance_data (RandomInstance *instance,
1167 while (((gsize) *buffer) & instance->alignment)
1168 *(*buffer)++ = '\0';
1170 random_instance_write (instance, *buffer);
1171 *buffer += instance->size;
1175 random_instance_assert (RandomInstance *instance,
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);
1194 return i == instance->size;
1198 random_instance_check (RandomInstance *instance,
1205 g_assert_cmpint ((gsize) buffer & ALIGN_BITS & instance->alignment, ==, 0);
1207 if (size != instance->size)
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))
1216 return i == instance->size;
1220 random_instance_filler (GVariantSerialised *serialised,
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);
1241 calculate_offset_size (gsize body_size,
1247 if (body_size + n_offsets <= G_MAXUINT8)
1250 if (body_size + 2 * n_offsets <= G_MAXUINT16)
1253 if (body_size + 4 * n_offsets <= G_MAXUINT32)
1256 /* the test case won't generate anything bigger */
1257 g_assert_not_reached ();
1261 flavoured_malloc (gsize size, gsize flavour)
1263 g_assert (flavour < 8);
1268 return ((gchar *) g_malloc (size + flavour)) + flavour;
1272 flavoured_free (gpointer data,
1277 g_free (((gchar *) data) - flavour);
1281 align_malloc (gsize size)
1285 #ifdef HAVE_POSIX_MEMALIGN
1286 if (posix_memalign (&mem, 8, size))
1287 g_error ("posix_memalign failed");
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
1293 mem = malloc (size);
1300 align_free (gpointer mem)
1306 append_offset (guchar **offset_ptr,
1312 guchar bytes[sizeof (gsize)];
1316 tmpvalue.integer = GSIZE_TO_LE (offset);
1317 memcpy (*offset_ptr, tmpvalue.bytes, offset_size);
1318 *offset_ptr += offset_size;
1322 prepend_offset (guchar **offset_ptr,
1328 guchar bytes[sizeof (gsize)];
1332 *offset_ptr -= offset_size;
1333 tmpvalue.integer = GSIZE_TO_LE (offset);
1334 memcpy (*offset_ptr, tmpvalue.bytes, offset_size);
1340 GVariantTypeInfo *type_info;
1341 RandomInstance *instance;
1345 instance = random_instance (NULL);
1348 const gchar *element;
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));
1357 needed_size = g_variant_serialiser_needed_size (type_info,
1358 random_instance_filler,
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);
1369 g_assert_cmpint (needed_size, ==, instance->size + 1);
1374 ptr = data = align_malloc (needed_size);
1375 append_instance_data (instance, &ptr);
1377 if (!instance->is_fixed_sized)
1380 g_assert_cmpint (ptr - data, ==, needed_size);
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);
1419 for (i = 0; i < 1000; i++)
1422 g_variant_type_info_assert_no_infos ();
1428 GVariantTypeInfo *element_info;
1429 GVariantTypeInfo *array_info;
1430 RandomInstance **instances;
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);
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,
1465 gsize element_fixed_size;
1466 gsize body_size = 0;
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)
1484 g_assert_cmpint (needed_size, ==, body_size + n_children * offset_size);
1488 guchar *offset_ptr, *body_ptr;
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);
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);
1545 for (i = 0; i < n_children; i++)
1546 random_instance_free (instances[i]);
1550 g_variant_type_info_unref (element_info);
1551 g_variant_type_info_unref (array_info);
1560 for (i = 0; i < 100; i++)
1563 g_variant_type_info_assert_no_infos ();
1569 GVariantTypeInfo *type_info;
1570 RandomInstance **instances;
1571 gboolean fixed_size;
1578 n_children = g_test_rand_int_range (0, MAX_TUPLE_CHILDREN);
1579 instances = g_new (RandomInstance *, n_children);
1582 GString *type_string;
1588 type_string = g_string_new ("(");
1589 for (i = 0; i < n_children; i++)
1593 instances[i] = random_instance (NULL);
1595 alignment |= instances[i]->alignment;
1596 if (!instances[i]->is_fixed_sized)
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,
1613 gsize body_size = 0;
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)
1627 body_size += (-body_size) & alignment;
1629 g_assert ((body_size == 0) == (n_children == 0));
1630 if (n_children == 0)
1634 offset_size = calculate_offset_size (body_size, offsets);
1635 g_assert_cmpint (needed_size, ==, body_size + offsets * offset_size);
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);
1656 while (((gsize) body_ptr) & alignment)
1659 g_assert ((body_ptr == data) == (n_children == 0));
1660 if (n_children == 0)
1666 g_assert (body_ptr == ofs_ptr);
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);
1708 for (i = 0; i < n_children; i++)
1709 random_instance_free (instances[i]);
1713 g_variant_type_info_unref (type_info);
1722 for (i = 0; i < 100; i++)
1725 g_variant_type_info_assert_no_infos ();
1731 GVariantTypeInfo *type_info;
1732 RandomInstance *instance;
1733 const gchar *type_string;
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);
1753 ptr = data = align_malloc (needed_size);
1754 append_instance_data (instance, &ptr);
1756 memcpy (ptr, type_string, len);
1759 g_assert (data + needed_size == ptr);
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);
1801 test_variants (void)
1805 for (i = 0; i < 100; i++)
1808 g_variant_type_info_assert_no_infos ();
1821 #define is_objpath is_string | 2
1822 #define is_sig is_string | 4
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" },
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}" }
1857 for (i = 0; i < G_N_ELEMENTS (test_cases); i++)
1861 flags = g_variant_serialiser_is_string (test_cases[i].data,
1865 flags |= g_variant_serialiser_is_object_path (test_cases[i].data,
1869 flags |= g_variant_serialiser_is_signature (test_cases[i].data,
1873 g_assert (flags == test_cases[i].flags);
1877 typedef struct _TreeInstance TreeInstance;
1878 struct _TreeInstance
1880 GVariantTypeInfo *info;
1882 TreeInstance **children;
1893 static GVariantType *
1894 make_random_definite_type (int depth)
1896 GString *description;
1897 GString *type_string;
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);
1910 make_random_string (gchar *string,
1912 const GVariantType *type)
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))];
1923 /* in case we need an object path, prefix a '/' */
1924 if (*g_variant_type_peek_string (type) == 'o')
1930 static TreeInstance *
1931 tree_instance_new (const GVariantType *type,
1934 const GVariantType *child_type = NULL;
1935 GVariantType *mytype = NULL;
1936 TreeInstance *instance;
1937 gboolean is_tuple_type;
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);
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);
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;
1969 case G_VARIANT_TYPE_INFO_CHAR_VARIANT:
1970 instance->n_children = 1;
1975 instance->data.integer = g_test_rand_int_range (0, 2);
1976 instance->data_size = 1;
1980 instance->data.integer = g_test_rand_int ();
1981 instance->data_size = 1;
1985 instance->data.integer = g_test_rand_int ();
1986 instance->data_size = 2;
1989 case 'i': case 'u': case 'h':
1990 instance->data.integer = g_test_rand_int ();
1991 instance->data_size = 4;
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;
2002 instance->data.floating = g_test_rand_double ();
2003 instance->data_size = 8;
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);
2012 if (instance->data_size == 0)
2013 /* no data -> it is a container */
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);
2024 child_type = g_variant_type_next (child_type);
2027 g_assert (!is_tuple_type || child_type == NULL);
2030 g_variant_type_free (mytype);
2036 tree_instance_free (TreeInstance *instance)
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;
2050 tree_filler (GVariantSerialised *serialised,
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)
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);
2075 if (serialised->size == 0)
2076 serialised->size = instance->data_size;
2078 if (serialised->data)
2080 switch (instance->data_size)
2083 *serialised->data = instance->data.integer;
2088 guint16 value = instance->data.integer;
2090 if (i_am_writing_byteswapped)
2091 value = GUINT16_SWAP_LE_BE (value);
2093 *(guint16 *) serialised->data = value;
2099 guint32 value = instance->data.integer;
2101 if (i_am_writing_byteswapped)
2102 value = GUINT32_SWAP_LE_BE (value);
2104 *(guint32 *) serialised->data = value;
2110 guint64 value = instance->data.integer;
2112 if (i_am_writing_byteswapped)
2113 value = GUINT64_SWAP_LE_BE (value);
2115 *(guint64 *) serialised->data = value;
2120 memcpy (serialised->data,
2121 instance->data.string,
2122 instance->data_size);
2130 check_tree (TreeInstance *instance,
2131 GVariantSerialised serialised)
2133 if (instance->info != serialised.type_info)
2136 if (instance->data_size == 0)
2137 /* is a container */
2141 if (g_variant_serialised_n_children (serialised) !=
2142 instance->n_children)
2145 for (i = 0; i < instance->n_children; i++)
2147 GVariantSerialised child;
2148 gpointer data = NULL;
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);
2167 switch (instance->data_size)
2170 g_assert (serialised.size == 1);
2171 return *(guint8 *) serialised.data ==
2172 (guint8) instance->data.integer;
2175 g_assert (serialised.size == 2);
2176 return *(guint16 *) serialised.data ==
2177 (guint16) instance->data.integer;
2180 g_assert (serialised.size == 4);
2181 return *(guint32 *) serialised.data ==
2182 (guint32) instance->data.integer;
2185 g_assert (serialised.size == 8);
2186 return *(guint64 *) serialised.data ==
2187 (guint64) instance->data.integer;
2190 if (serialised.size != instance->data_size)
2193 return memcmp (serialised.data,
2194 instance->data.string,
2195 instance->data_size) == 0;
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);
2213 test_byteswap (void)
2215 GVariantSerialised one, two;
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_cmpint (one.size, ==, two.size);
2228 g_assert (memcmp (one.data, two.data, one.size) == 0);
2230 tree_instance_free (tree);
2236 test_byteswaps (void)
2240 for (i = 0; i < 200; i++)
2243 g_variant_type_info_assert_no_infos ();
2247 test_fuzz (gdouble *fuzziness)
2249 GVariantSerialised serialised;
2252 /* make an instance */
2253 tree = tree_instance_new (NULL, 3);
2256 serialise_tree (tree, &serialised);
2258 g_assert (g_variant_serialised_is_normal (serialised));
2259 g_assert (check_tree (tree, serialised));
2261 if (serialised.size)
2263 gboolean fuzzed = FALSE;
2270 for (i = 0; i < serialised.size; i++)
2271 if (randomly (*fuzziness))
2273 serialised.data[i] += g_test_rand_int_range (1, 256);
2278 /* at least one byte in the serialised data has changed.
2280 * this means that at least one of the following is true:
2282 * - the serialised data now represents a different value:
2283 * check_tree() will return FALSE
2285 * - the serialised data is in non-normal form:
2286 * g_variant_serialiser_is_normal() will return FALSE
2288 * we always do both checks to increase exposure of the serialiser
2291 a = g_variant_serialised_is_normal (serialised);
2292 b = check_tree (tree, serialised);
2294 g_assert (!a || !b);
2297 tree_instance_free (tree);
2298 g_free (serialised.data);
2303 test_fuzzes (gpointer data)
2308 fuzziness = GPOINTER_TO_INT (data) / 100.;
2310 for (i = 0; i < 200; i++)
2311 test_fuzz (&fuzziness);
2313 g_variant_type_info_assert_no_infos ();
2317 tree_instance_get_gvariant (TreeInstance *tree)
2319 const GVariantType *type;
2322 type = (GVariantType *) g_variant_type_info_get_type_string (tree->info);
2324 switch (g_variant_type_info_get_type_char (tree->info))
2326 case G_VARIANT_TYPE_INFO_CHAR_MAYBE:
2328 const GVariantType *child_type;
2331 if (tree->n_children)
2332 child = tree_instance_get_gvariant (tree->children[0]);
2336 child_type = g_variant_type_element (type);
2338 if (child != NULL && randomly (0.5))
2341 result = g_variant_new_maybe (child_type, child);
2345 case G_VARIANT_TYPE_INFO_CHAR_ARRAY:
2347 const GVariantType *child_type;
2348 GVariant **children;
2351 children = g_new (GVariant *, tree->n_children);
2352 for (i = 0; i < tree->n_children; i++)
2353 children[i] = tree_instance_get_gvariant (tree->children[i]);
2355 child_type = g_variant_type_element (type);
2357 if (i > 0 && randomly (0.5))
2360 result = g_variant_new_array (child_type, children, tree->n_children);
2365 case G_VARIANT_TYPE_INFO_CHAR_TUPLE:
2367 GVariant **children;
2370 children = g_new (GVariant *, tree->n_children);
2371 for (i = 0; i < tree->n_children; i++)
2372 children[i] = tree_instance_get_gvariant (tree->children[i]);
2374 result = g_variant_new_tuple (children, tree->n_children);
2379 case G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY:
2381 GVariant *key, *val;
2383 g_assert (tree->n_children == 2);
2385 key = tree_instance_get_gvariant (tree->children[0]);
2386 val = tree_instance_get_gvariant (tree->children[1]);
2388 result = g_variant_new_dict_entry (key, val);
2392 case G_VARIANT_TYPE_INFO_CHAR_VARIANT:
2396 g_assert (tree->n_children == 1);
2398 value = tree_instance_get_gvariant (tree->children[0]);
2399 result = g_variant_new_variant (value);
2404 result = g_variant_new_boolean (tree->data.integer > 0);
2408 result = g_variant_new_byte (tree->data.integer);
2412 result = g_variant_new_int16 (tree->data.integer);
2416 result = g_variant_new_uint16 (tree->data.integer);
2420 result = g_variant_new_int32 (tree->data.integer);
2424 result = g_variant_new_uint32 (tree->data.integer);
2428 result = g_variant_new_int64 (tree->data.integer);
2432 result = g_variant_new_uint64 (tree->data.integer);
2436 result = g_variant_new_handle (tree->data.integer);
2440 result = g_variant_new_double (tree->data.floating);
2444 result = g_variant_new_string (tree->data.string);
2448 result = g_variant_new_object_path (tree->data.string);
2452 result = g_variant_new_signature (tree->data.string);
2456 g_assert_not_reached ();
2463 tree_instance_check_gvariant (TreeInstance *tree,
2466 const GVariantType *type;
2468 type = (GVariantType *) g_variant_type_info_get_type_string (tree->info);
2469 g_assert (g_variant_is_of_type (value, type));
2471 switch (g_variant_type_info_get_type_char (tree->info))
2473 case G_VARIANT_TYPE_INFO_CHAR_MAYBE:
2478 child = g_variant_get_maybe (value);
2480 if (child != NULL && tree->n_children == 1)
2481 equal = tree_instance_check_gvariant (tree->children[0], child);
2482 else if (child == NULL && tree->n_children == 0)
2488 g_variant_unref (child);
2494 case G_VARIANT_TYPE_INFO_CHAR_ARRAY:
2495 case G_VARIANT_TYPE_INFO_CHAR_TUPLE:
2496 case G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY:
2500 if (g_variant_n_children (value) != tree->n_children)
2503 for (i = 0; i < tree->n_children; i++)
2508 child = g_variant_get_child_value (value, i);
2509 equal = tree_instance_check_gvariant (tree->children[i], child);
2510 g_variant_unref (child);
2520 case G_VARIANT_TYPE_INFO_CHAR_VARIANT:
2522 const gchar *str1, *str2;
2526 child = g_variant_get_variant (value);
2527 str1 = g_variant_get_type_string (child);
2528 str2 = g_variant_type_info_get_type_string (tree->children[0]->info);
2529 /* GVariant only keeps one copy of type strings around */
2530 equal = str1 == str2 &&
2531 tree_instance_check_gvariant (tree->children[0], child);
2533 g_variant_unref (child);
2540 return g_variant_get_boolean (value) == tree->data.integer;
2543 return g_variant_get_byte (value) == (guchar) tree->data.integer;
2546 return g_variant_get_int16 (value) == (gint16) tree->data.integer;
2549 return g_variant_get_uint16 (value) == (guint16) tree->data.integer;
2552 return g_variant_get_int32 (value) == (gint32) tree->data.integer;
2555 return g_variant_get_uint32 (value) == (guint32) tree->data.integer;
2558 return g_variant_get_int64 (value) == (gint64) tree->data.integer;
2561 return g_variant_get_uint64 (value) == (guint64) tree->data.integer;
2564 return g_variant_get_handle (value) == (gint32) tree->data.integer;
2568 gdouble floating = g_variant_get_double (value);
2570 return memcmp (&floating, &tree->data.floating, sizeof floating) == 0;
2576 return strcmp (g_variant_get_string (value, NULL),
2577 tree->data.string) == 0;
2580 g_assert_not_reached ();
2585 tree_instance_build_gvariant (TreeInstance *tree,
2586 GVariantBuilder *builder,
2589 const GVariantType *type;
2591 type = (GVariantType *) g_variant_type_info_get_type_string (tree->info);
2593 if (g_variant_type_is_container (type))
2597 /* force GVariantBuilder to guess the type half the time */
2598 if (guess_ok && randomly (0.5))
2600 if (g_variant_type_is_array (type) && tree->n_children)
2601 type = G_VARIANT_TYPE_ARRAY;
2603 if (g_variant_type_is_maybe (type) && tree->n_children)
2604 type = G_VARIANT_TYPE_MAYBE;
2606 if (g_variant_type_is_tuple (type))
2607 type = G_VARIANT_TYPE_TUPLE;
2609 if (g_variant_type_is_dict_entry (type))
2610 type = G_VARIANT_TYPE_DICT_ENTRY;
2615 g_variant_builder_open (builder, type);
2617 for (i = 0; i < tree->n_children; i++)
2618 tree_instance_build_gvariant (tree->children[i], builder, guess_ok);
2620 g_variant_builder_close (builder);
2623 g_variant_builder_add_value (builder, tree_instance_get_gvariant (tree));
2628 tree_instance_check_iter (TreeInstance *tree,
2633 value = g_variant_iter_next_value (iter);
2635 if (g_variant_is_container (value))
2639 iter = g_variant_iter_new (value);
2640 g_variant_unref (value);
2642 if (g_variant_iter_n_children (iter) != tree->n_children)
2644 g_variant_iter_free (iter);
2648 for (i = 0; i < tree->n_children; i++)
2649 if (!tree_instance_check_iter (tree->children[i], iter))
2651 g_variant_iter_free (iter);
2655 g_assert (g_variant_iter_next_value (iter) == NULL);
2656 g_variant_iter_free (iter);
2665 equal = tree_instance_check_gvariant (tree, value);
2666 g_variant_unref (value);
2673 test_container (void)
2679 tree = tree_instance_new (NULL, 3);
2680 value = g_variant_ref_sink (tree_instance_get_gvariant (tree));
2682 s1 = g_variant_print (value, TRUE);
2683 g_assert (tree_instance_check_gvariant (tree, value));
2685 g_variant_get_data (value);
2687 s2 = g_variant_print (value, TRUE);
2688 g_assert (tree_instance_check_gvariant (tree, value));
2690 g_assert_cmpstr (s1, ==, s2);
2692 if (g_variant_is_container (value))
2694 GVariantBuilder builder;
2700 g_variant_builder_init (&builder, G_VARIANT_TYPE_VARIANT);
2701 tree_instance_build_gvariant (tree, &builder, TRUE);
2702 built = g_variant_builder_end (&builder);
2703 g_variant_ref_sink (built);
2704 g_variant_get_data (built);
2705 val = g_variant_get_variant (built);
2707 s3 = g_variant_print (val, TRUE);
2708 g_assert_cmpstr (s1, ==, s3);
2710 g_variant_iter_init (&iter, built);
2711 g_assert (tree_instance_check_iter (tree, &iter));
2712 g_assert (g_variant_iter_next_value (&iter) == NULL);
2714 g_variant_unref (built);
2715 g_variant_unref (val);
2719 tree_instance_free (tree);
2720 g_variant_unref (value);
2728 /* Test some different methods of creating strings */
2731 v = g_variant_new_string ("foo");
2732 g_assert_cmpstr (g_variant_get_string (v, NULL), ==, "foo");
2733 g_variant_unref (v);
2736 v = g_variant_new_take_string (g_strdup ("foo"));
2737 g_assert_cmpstr (g_variant_get_string (v, NULL), ==, "foo");
2738 g_variant_unref (v);
2740 v = g_variant_new_printf ("%s %d", "foo", 123);
2741 g_assert_cmpstr (g_variant_get_string (v, NULL), ==, "foo 123");
2742 g_variant_unref (v);
2748 const gchar invalid[] = "hello\xffworld";
2751 /* ensure that the test data is not valid utf8... */
2752 g_assert (!g_utf8_validate (invalid, -1, NULL));
2754 /* load the data untrusted */
2755 value = g_variant_new_from_data (G_VARIANT_TYPE_STRING,
2756 invalid, sizeof invalid,
2759 /* ensure that the problem is caught and we get valid UTF-8 */
2760 g_assert (g_utf8_validate (g_variant_get_string (value, NULL), -1, NULL));
2761 g_variant_unref (value);
2764 /* now load it trusted */
2765 value = g_variant_new_from_data (G_VARIANT_TYPE_STRING,
2766 invalid, sizeof invalid,
2769 /* ensure we get the invalid data (ie: make sure that time wasn't
2770 * wasted on validating data that was marked as trusted)
2772 g_assert (g_variant_get_string (value, NULL) == invalid);
2773 g_variant_unref (value);
2777 test_containers (void)
2781 for (i = 0; i < 100; i++)
2786 g_variant_type_info_assert_no_infos ();
2790 test_format_strings (void)
2795 g_assert (g_variant_format_string_scan ("i", NULL, &end) && *end == '\0');
2796 g_assert (g_variant_format_string_scan ("@i", NULL, &end) && *end == '\0');
2797 g_assert (g_variant_format_string_scan ("@ii", NULL, &end) && *end == 'i');
2798 g_assert (g_variant_format_string_scan ("^a&s", NULL, &end) && *end == '\0');
2799 g_assert (g_variant_format_string_scan ("(^as)", NULL, &end) &&
2801 g_assert (!g_variant_format_string_scan ("(^s)", NULL, &end));
2802 g_assert (!g_variant_format_string_scan ("(^a)", NULL, &end));
2803 g_assert (!g_variant_format_string_scan ("(z)", NULL, &end));
2804 g_assert (!g_variant_format_string_scan ("az", NULL, &end));
2805 g_assert (!g_variant_format_string_scan ("{**}", NULL, &end));
2806 g_assert (!g_variant_format_string_scan ("{@**}", NULL, &end));
2807 g_assert (g_variant_format_string_scan ("{@y*}", NULL, &end) &&
2809 g_assert (g_variant_format_string_scan ("{yv}", NULL, &end) &&
2811 g_assert (!g_variant_format_string_scan ("{&?v}", NULL, &end));
2812 g_assert (g_variant_format_string_scan ("{@?v}", 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 g_assert (g_variant_format_string_scan ("{&sv}", NULL, &end) &&
2818 g_assert (!g_variant_format_string_scan ("{vv}", NULL, &end));
2819 g_assert (!g_variant_format_string_scan ("{y}", NULL, &end));
2820 g_assert (!g_variant_format_string_scan ("{yyy}", NULL, &end));
2821 g_assert (!g_variant_format_string_scan ("{ya}", NULL, &end));
2822 g_assert (g_variant_format_string_scan ("&s", NULL, &end) && *end == '\0');
2823 g_assert (!g_variant_format_string_scan ("&as", NULL, &end));
2824 g_assert (!g_variant_format_string_scan ("@z", NULL, &end));
2825 g_assert (!g_variant_format_string_scan ("az", NULL, &end));
2826 g_assert (!g_variant_format_string_scan ("a&s", NULL, &end));
2828 type = g_variant_format_string_scan_type ("mm(@xy^a&s*?@?)", NULL, &end);
2829 g_assert (type && *end == '\0');
2830 g_assert (g_variant_type_equal (type, G_VARIANT_TYPE ("mm(xyas*?\?)")));
2831 g_variant_type_free (type);
2833 type = g_variant_format_string_scan_type ("mm(@xy^a&*?@?)", NULL, NULL);
2834 g_assert (type == NULL);
2838 do_failed_test (const char *test,
2839 const gchar *pattern)
2841 g_test_trap_subprocess (test, 1000000, 0);
2842 g_test_trap_assert_failed ();
2843 g_test_trap_assert_stderr (pattern);
2847 test_invalid_varargs (void)
2852 if (!g_test_undefined ())
2855 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
2856 "*GVariant format string*");
2857 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
2858 "*valid_format_string*");
2859 value = g_variant_new ("z");
2860 g_test_assert_expected_messages ();
2861 g_assert (value == NULL);
2863 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
2864 "*valid GVariant format string as a prefix*");
2865 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
2866 "*valid_format_string*");
2867 value = g_variant_new_va ("z", &end, NULL);
2868 g_test_assert_expected_messages ();
2869 g_assert (value == NULL);
2871 value = g_variant_new ("y", 'a');
2872 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
2873 "*type of 'q' but * has a type of 'y'*");
2874 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
2875 "*valid_format_string*");
2876 g_variant_get (value, "q");
2877 g_test_assert_expected_messages ();
2878 g_variant_unref (value);
2882 check_and_free (GVariant *value,
2885 gchar *valstr = g_variant_print (value, FALSE);
2886 g_assert_cmpstr (str, ==, valstr);
2887 g_variant_unref (value);
2892 test_varargs_empty_array (void)
2894 g_variant_new ("(a{s*})", NULL);
2896 g_assert_not_reached ();
2903 GVariantBuilder array;
2905 g_variant_builder_init (&array, G_VARIANT_TYPE_ARRAY);
2906 g_variant_builder_add_parsed (&array, "{'size', <(%i, %i)> }", 800, 600);
2907 g_variant_builder_add (&array, "{sv}", "title",
2908 g_variant_new_string ("Test case"));
2909 g_variant_builder_add_value (&array,
2910 g_variant_new_dict_entry (g_variant_new_string ("temperature"),
2911 g_variant_new_variant (
2912 g_variant_new_double (37.5))));
2913 check_and_free (g_variant_new ("(ma{sv}m(a{sv})ma{sv}ii)",
2914 NULL, FALSE, NULL, &array, 7777, 8888),
2915 "(nothing, nothing, {'size': <(800, 600)>, "
2916 "'title': <'Test case'>, "
2917 "'temperature': <37.5>}, "
2920 check_and_free (g_variant_new ("(imimimmimmimmi)",
2927 "(123, nothing, 123, nothing, just nothing, 123)");
2929 check_and_free (g_variant_new ("(ybnixd)",
2930 'a', 1, 22, 33, (guint64) 44, 5.5),
2931 "(0x61, true, 22, 33, 44, 5.5)");
2933 check_and_free (g_variant_new ("(@y?*rv)",
2934 g_variant_new ("y", 'a'),
2935 g_variant_new ("y", 'b'),
2936 g_variant_new ("y", 'c'),
2937 g_variant_new ("(y)", 'd'),
2938 g_variant_new ("y", 'e')),
2939 "(0x61, 0x62, 0x63, (0x64,), <byte 0x65>)");
2943 GVariantBuilder array;
2950 g_variant_builder_init (&array, G_VARIANT_TYPE_ARRAY);
2951 for (i = 0; i < 100; i++)
2953 number = g_strdup_printf ("%d", i);
2954 g_variant_builder_add (&array, "s", number);
2958 value = g_variant_builder_end (&array);
2959 g_variant_iter_init (&iter, value);
2962 while (g_variant_iter_loop (&iter, "s", &number))
2964 gchar *check = g_strdup_printf ("%d", i++);
2965 g_assert_cmpstr (number, ==, check);
2968 g_assert (number == NULL);
2969 g_assert (i == 100);
2971 g_variant_unref (value);
2973 g_variant_builder_init (&array, G_VARIANT_TYPE_ARRAY);
2974 for (i = 0; i < 100; i++)
2975 g_variant_builder_add (&array, "mi", i % 2 == 0, i);
2976 value = g_variant_builder_end (&array);
2979 g_variant_iter_init (&iter, value);
2980 while (g_variant_iter_loop (&iter, "mi", NULL, &val))
2981 g_assert (val == i++ || val == 0);
2982 g_assert (i == 100);
2985 g_variant_iter_init (&iter, value);
2986 while (g_variant_iter_loop (&iter, "mi", &just, &val))
2993 g_assert (val == this);
2998 g_assert (val == 0);
3001 g_assert (i == 100);
3003 g_variant_unref (value);
3007 const gchar *strvector[] = {"/hello", "/world", NULL};
3008 const gchar *test_strs[] = {"/foo", "/bar", "/baz" };
3009 GVariantBuilder builder;
3010 GVariantIter *array;
3018 g_variant_builder_init (&builder, G_VARIANT_TYPE ("as"));
3019 g_variant_builder_add (&builder, "s", "/foo");
3020 g_variant_builder_add (&builder, "s", "/bar");
3021 g_variant_builder_add (&builder, "s", "/baz");
3022 value = g_variant_new("(as^as^a&s)", &builder, strvector, strvector);
3023 g_variant_iter_init (&tuple, value);
3024 g_variant_iter_next (&tuple, "as", &array);
3027 while (g_variant_iter_loop (array, "s", &str))
3028 g_assert_cmpstr (str, ==, test_strs[i++]);
3031 g_variant_iter_free (array);
3034 g_variant_iter_init (&tuple, value);
3035 g_variant_iter_next (&tuple, "as", &array);
3038 while (g_variant_iter_loop (array, "&s", &str))
3039 g_assert_cmpstr (str, ==, test_strs[i++]);
3042 g_variant_iter_free (array);
3044 g_variant_iter_next (&tuple, "^a&s", &strv);
3045 g_variant_iter_next (&tuple, "^as", &my_strv);
3047 g_assert_cmpstr (strv[0], ==, "/hello");
3048 g_assert_cmpstr (strv[1], ==, "/world");
3049 g_assert (strv[2] == NULL);
3050 g_assert_cmpstr (my_strv[0], ==, "/hello");
3051 g_assert_cmpstr (my_strv[1], ==, "/world");
3052 g_assert (my_strv[2] == NULL);
3054 g_variant_unref (value);
3055 g_strfreev (my_strv);
3060 const gchar *strvector[] = {"/hello", "/world", NULL};
3061 const gchar *test_strs[] = {"/foo", "/bar", "/baz" };
3062 GVariantBuilder builder;
3063 GVariantIter *array;
3071 g_variant_builder_init (&builder, G_VARIANT_TYPE_OBJECT_PATH_ARRAY);
3072 g_variant_builder_add (&builder, "o", "/foo");
3073 g_variant_builder_add (&builder, "o", "/bar");
3074 g_variant_builder_add (&builder, "o", "/baz");
3075 value = g_variant_new("(ao^ao^a&o)", &builder, strvector, strvector);
3076 g_variant_iter_init (&tuple, value);
3077 g_variant_iter_next (&tuple, "ao", &array);
3080 while (g_variant_iter_loop (array, "o", &str))
3081 g_assert_cmpstr (str, ==, test_strs[i++]);
3084 g_variant_iter_free (array);
3087 g_variant_iter_init (&tuple, value);
3088 g_variant_iter_next (&tuple, "ao", &array);
3091 while (g_variant_iter_loop (array, "&o", &str))
3092 g_assert_cmpstr (str, ==, test_strs[i++]);
3095 g_variant_iter_free (array);
3097 g_variant_iter_next (&tuple, "^a&o", &strv);
3098 g_variant_iter_next (&tuple, "^ao", &my_strv);
3100 g_assert_cmpstr (strv[0], ==, "/hello");
3101 g_assert_cmpstr (strv[1], ==, "/world");
3102 g_assert (strv[2] == NULL);
3103 g_assert_cmpstr (my_strv[0], ==, "/hello");
3104 g_assert_cmpstr (my_strv[1], ==, "/world");
3105 g_assert (my_strv[2] == NULL);
3107 g_variant_unref (value);
3108 g_strfreev (my_strv);
3113 const gchar *strvector[] = { "i", "ii", "iii", "iv", "v", "vi", NULL };
3114 GVariantBuilder builder;
3123 g_variant_builder_init (&builder, G_VARIANT_TYPE ("aas"));
3124 g_variant_builder_open (&builder, G_VARIANT_TYPE ("as"));
3125 for (i = 0; i < 6; i++)
3127 g_variant_builder_add (&builder, "s", strvector[i]);
3129 g_variant_builder_add (&builder, "&s", strvector[i]);
3130 g_variant_builder_close (&builder);
3131 g_variant_builder_add (&builder, "^as", strvector);
3132 g_variant_builder_add (&builder, "^as", strvector);
3133 value = g_variant_new ("aas", &builder);
3135 g_variant_iter_init (&iter, value);
3136 while (g_variant_iter_loop (&iter, "^as", &strv))
3137 for (i = 0; i < 6; i++)
3138 g_assert_cmpstr (strv[i], ==, strvector[i]);
3140 g_variant_iter_init (&iter, value);
3141 while (g_variant_iter_loop (&iter, "^a&s", &strv))
3142 for (i = 0; i < 6; i++)
3143 g_assert_cmpstr (strv[i], ==, strvector[i]);
3145 g_variant_iter_init (&iter, value);
3146 while (g_variant_iter_loop (&iter, "as", &i2))
3151 while (g_variant_iter_loop (i2, "s", &str))
3152 g_assert_cmpstr (str, ==, strvector[i++]);
3156 g_variant_iter_init (&iter, value);
3157 i3 = g_variant_iter_copy (&iter);
3158 while (g_variant_iter_loop (&iter, "@as", &sub))
3160 gchar *str = g_variant_print (sub, TRUE);
3161 g_assert_cmpstr (str, ==,
3162 "['i', 'ii', 'iii', 'iv', 'v', 'vi']");
3166 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
3167 "*NULL has already been returned*");
3168 g_variant_iter_next_value (&iter);
3169 g_test_assert_expected_messages ();
3171 while (g_variant_iter_loop (i3, "*", &sub))
3173 gchar *str = g_variant_print (sub, TRUE);
3174 g_assert_cmpstr (str, ==,
3175 "['i', 'ii', 'iii', 'iv', 'v', 'vi']");
3179 g_variant_iter_free (i3);
3181 for (i = 0; i < g_variant_n_children (value); i++)
3185 g_variant_get_child (value, i, "*", &sub);
3187 for (j = 0; j < g_variant_n_children (sub); j++)
3189 const gchar *str = NULL;
3192 g_variant_get_child (sub, j, "&s", &str);
3193 g_assert_cmpstr (str, ==, strvector[j]);
3195 cval = g_variant_get_child_value (sub, j);
3196 g_variant_get (cval, "&s", &str);
3197 g_assert_cmpstr (str, ==, strvector[j]);
3198 g_variant_unref (cval);
3201 g_variant_unref (sub);
3204 g_variant_unref (value);
3223 /* test all 'nothing' */
3224 value = g_variant_new ("(mymbmnmqmimumxmtmhmdmv)",
3227 FALSE, (gint16) 123,
3228 FALSE, (guint16) 123,
3229 FALSE, (gint32) 123,
3230 FALSE, (guint32) 123,
3231 FALSE, (gint64) 123,
3232 FALSE, (guint64) 123,
3234 FALSE, (gdouble) 37.5,
3238 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3252 memset (justs, 1, sizeof justs);
3253 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3265 g_assert (!(justs[0] || justs[1] || justs[2] || justs[3] || justs[4] ||
3266 justs[5] || justs[6] || justs[7] || justs[8] || justs[9]));
3269 memset (justs, 1, sizeof justs);
3270 byteval = i16val = u16val = i32val = u32val = i64val = u64val = hval = 88;
3274 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3275 &justs[0], &byteval,
3286 g_assert (!(justs[0] || justs[1] || justs[2] || justs[3] || justs[4] ||
3287 justs[5] || justs[6] || justs[7] || justs[8] || justs[9]));
3288 g_assert (byteval == '\0' && bval == FALSE);
3289 g_assert (i16val == 0 && u16val == 0 && i32val == 0 &&
3290 u32val == 0 && i64val == 0 && u64val == 0 &&
3291 hval == 0 && dval == 0.0);
3292 g_assert (vval == NULL);
3295 byteval = i16val = u16val = i32val = u32val = i64val = u64val = hval = 88;
3299 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3311 g_assert (byteval == '\0' && bval == FALSE);
3312 g_assert (i16val == 0 && u16val == 0 && i32val == 0 &&
3313 u32val == 0 && i64val == 0 && u64val == 0 &&
3314 hval == 0 && dval == 0.0);
3315 g_assert (vval == NULL);
3317 g_variant_unref (value);
3320 /* test all 'just' */
3321 value = g_variant_new ("(mymbmnmqmimumxmtmhmdmv)",
3325 TRUE, (guint16) 123,
3327 TRUE, (guint32) 123,
3329 TRUE, (guint64) 123,
3331 TRUE, (gdouble) 37.5,
3332 g_variant_new ("()"));
3335 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3349 memset (justs, 0, sizeof justs);
3350 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3362 g_assert (justs[0] && justs[1] && justs[2] && justs[3] && justs[4] &&
3363 justs[5] && justs[6] && justs[7] && justs[8] && justs[9]);
3366 memset (justs, 0, sizeof justs);
3367 byteval = i16val = u16val = i32val = u32val = i64val = u64val = hval = 88;
3371 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3372 &justs[0], &byteval,
3383 g_assert (justs[0] && justs[1] && justs[2] && justs[3] && justs[4] &&
3384 justs[5] && justs[6] && justs[7] && justs[8] && justs[9]);
3385 g_assert (byteval == 'a' && bval == TRUE);
3386 g_assert (i16val == 123 && u16val == 123 && i32val == 123 &&
3387 u32val == 123 && i64val == 123 && u64val == 123 &&
3388 hval == -1 && dval == 37.5);
3389 g_assert (g_variant_is_of_type (vval, G_VARIANT_TYPE_UNIT));
3390 g_variant_unref (vval);
3393 byteval = i16val = u16val = i32val = u32val = i64val = u64val = hval = 88;
3397 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3409 g_assert (byteval == 'a' && bval == TRUE);
3410 g_assert (i16val == 123 && u16val == 123 && i32val == 123 &&
3411 u32val == 123 && i64val == 123 && u64val == 123 &&
3412 hval == -1 && dval == 37.5);
3413 g_assert (g_variant_is_of_type (vval, G_VARIANT_TYPE_UNIT));
3414 g_variant_unref (vval);
3416 g_variant_unref (value);
3423 value = g_variant_new ("(masas)", NULL, NULL);
3424 g_variant_ref_sink (value);
3426 str = g_variant_print (value, TRUE);
3427 g_assert_cmpstr (str, ==, "(@mas nothing, @as [])");
3428 g_variant_unref (value);
3431 do_failed_test ("/gvariant/varargs/subprocess/empty-array",
3432 "*which type of empty array*");
3435 g_variant_type_info_assert_no_infos ();
3439 hash_get (GVariant *value,
3440 const gchar *format,
3443 const gchar *endptr = NULL;
3447 hash = g_str_has_suffix (format, "#");
3449 va_start (ap, format);
3450 g_variant_get_va (value, format, hash ? &endptr : NULL, &ap);
3454 g_assert (*endptr == '#');
3458 hash_new (const gchar *format,
3461 const gchar *endptr = NULL;
3466 hash = g_str_has_suffix (format, "#");
3468 va_start (ap, format);
3469 value = g_variant_new_va (format, hash ? &endptr : NULL, &ap);
3473 g_assert (*endptr == '#');
3485 value = hash_new ("i", 234);
3486 hash_get (value, "i", &x);
3487 g_assert (x == 234);
3488 g_variant_unref (value);
3491 value = hash_new ("i#", 234);
3492 hash_get (value, "i#", &x);
3493 g_assert (x == 234);
3494 g_variant_unref (value);
3496 g_variant_type_info_assert_no_infos ();
3500 test_builder_memory (void)
3502 GVariantBuilder *hb;
3505 hb = g_variant_builder_new (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_open (hb, G_VARIANT_TYPE_ARRAY);
3509 g_variant_builder_add (hb, "s", "some value");
3510 g_variant_builder_ref (hb);
3511 g_variant_builder_unref (hb);
3512 g_variant_builder_unref (hb);
3514 hb = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
3515 g_variant_builder_unref (hb);
3517 hb = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
3518 g_variant_builder_clear (hb);
3519 g_variant_builder_unref (hb);
3521 g_variant_builder_init (&sb, G_VARIANT_TYPE_ARRAY);
3522 g_variant_builder_open (&sb, G_VARIANT_TYPE_ARRAY);
3523 g_variant_builder_open (&sb, G_VARIANT_TYPE_ARRAY);
3524 g_variant_builder_add (&sb, "s", "some value");
3525 g_variant_builder_clear (&sb);
3527 g_variant_type_info_assert_no_infos ();
3533 GVariant *items[4096];
3537 table = g_hash_table_new_full (g_variant_hash, g_variant_equal,
3538 (GDestroyNotify ) g_variant_unref,
3541 for (i = 0; i < G_N_ELEMENTS (items); i++)
3547 tree = tree_instance_new (NULL, 0);
3548 items[i] = tree_instance_get_gvariant (tree);
3549 tree_instance_free (tree);
3551 for (j = 0; j < i; j++)
3552 if (g_variant_equal (items[i], items[j]))
3554 g_variant_unref (items[i]);
3558 g_hash_table_insert (table,
3559 g_variant_ref_sink (items[i]),
3560 GINT_TO_POINTER (i));
3563 for (i = 0; i < G_N_ELEMENTS (items); i++)
3567 result = g_hash_table_lookup (table, items[i]);
3568 g_assert_cmpint (GPOINTER_TO_INT (result), ==, i);
3571 g_hash_table_unref (table);
3573 g_variant_type_info_assert_no_infos ();
3577 test_gv_byteswap (void)
3579 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
3580 # define native16(x) x, 0
3581 # define swapped16(x) 0, x
3583 # define native16(x) 0, x
3584 # define swapped16(x) x, 0
3586 /* all kinds of of crazy randomised testing already performed on the
3587 * byteswapper in the /gvariant/serialiser/byteswap test and all kinds
3588 * of crazy randomised testing performed against the serialiser
3589 * normalisation functions in the /gvariant/serialiser/fuzz/ tests.
3591 * just test a few simple cases here to make sure they each work
3593 guchar validbytes[] = { 'a', '\0', swapped16(66), 2,
3595 'b', '\0', swapped16(77), 2,
3597 guchar corruptbytes[] = { 'a', '\0', swapped16(66), 2,
3599 'b', '\0', swapped16(77), 2,
3601 guint valid_data[4], corrupt_data[4];
3602 GVariant *value, *swapped;
3603 gchar *string, *string2;
3605 memcpy (valid_data, validbytes, sizeof validbytes);
3606 memcpy (corrupt_data, corruptbytes, sizeof corruptbytes);
3609 value = g_variant_new_from_data (G_VARIANT_TYPE ("a(sn)"),
3610 valid_data, sizeof validbytes, TRUE,
3612 swapped = g_variant_byteswap (value);
3613 g_variant_unref (value);
3614 g_assert (g_variant_get_size (swapped) == 13);
3615 string = g_variant_print (swapped, FALSE);
3616 g_variant_unref (swapped);
3617 g_assert_cmpstr (string, ==, "[('a', 66), ('b', 77)]");
3620 /* untrusted but valid */
3621 value = g_variant_new_from_data (G_VARIANT_TYPE ("a(sn)"),
3622 valid_data, sizeof validbytes, FALSE,
3624 swapped = g_variant_byteswap (value);
3625 g_variant_unref (value);
3626 g_assert (g_variant_get_size (swapped) == 13);
3627 string = g_variant_print (swapped, FALSE);
3628 g_variant_unref (swapped);
3629 g_assert_cmpstr (string, ==, "[('a', 66), ('b', 77)]");
3632 /* untrusted, invalid */
3633 value = g_variant_new_from_data (G_VARIANT_TYPE ("a(sn)"),
3634 corrupt_data, sizeof corruptbytes, FALSE,
3636 string = g_variant_print (value, FALSE);
3637 swapped = g_variant_byteswap (value);
3638 g_variant_unref (value);
3639 g_assert (g_variant_get_size (swapped) == 13);
3640 value = g_variant_byteswap (swapped);
3641 g_variant_unref (swapped);
3642 string2 = g_variant_print (value, FALSE);
3643 g_assert (g_variant_get_size (value) == 13);
3644 g_variant_unref (value);
3645 g_assert_cmpstr (string, ==, string2);
3659 tree = tree_instance_new (NULL, 3);
3660 value = tree_instance_get_gvariant (tree);
3661 tree_instance_free (tree);
3663 pt = g_variant_print (value, TRUE);
3664 p = g_variant_print (value, FALSE);
3666 parsed = g_variant_parse (NULL, pt, NULL, NULL, NULL);
3667 res = g_variant_print (parsed, FALSE);
3668 g_assert_cmpstr (p, ==, res);
3669 g_variant_unref (parsed);
3672 parsed = g_variant_parse (g_variant_get_type (value), p,
3674 res = g_variant_print (parsed, TRUE);
3675 g_assert_cmpstr (pt, ==, res);
3676 g_variant_unref (parsed);
3679 g_variant_unref (value);
3689 for (i = 0; i < 100; i++)
3696 GError *error = NULL;
3701 for (i = 0; i < 127; i++)
3705 val = g_variant_new_string (str);
3706 p = g_variant_print (val, FALSE);
3707 g_variant_unref (val);
3709 val = g_variant_parse (NULL, p, NULL, NULL, &error);
3710 p2 = g_variant_print (val, FALSE);
3712 g_assert_cmpstr (str, ==, g_variant_get_string (val, NULL));
3713 g_assert_cmpstr (p, ==, p2);
3715 g_variant_unref (val);
3720 /* another mini test */
3725 value = g_variant_parse (G_VARIANT_TYPE_INT32, "1 2 3", NULL, &end, NULL);
3726 g_assert_cmpint (g_variant_get_int32 (value), ==, 1);
3727 /* make sure endptr returning works */
3728 g_assert_cmpstr (end, ==, " 2 3");
3729 g_variant_unref (value);
3732 /* unicode mini test */
3735 const gchar orig[] = "a\xc5\x82\xf0\x9d\x84\x9e \t\n";
3739 value = g_variant_new_string (orig);
3740 printed = g_variant_print (value, FALSE);
3741 g_variant_unref (value);
3743 g_assert_cmpstr (printed, ==, "'a\xc5\x82\xf0\x9d\x84\x9e \\t\\n'");
3744 value = g_variant_parse (NULL, printed, NULL, NULL, NULL);
3745 g_assert_cmpstr (g_variant_get_string (value, NULL), ==, orig);
3746 g_variant_unref (value);
3752 const gchar orig[] = " \342\200\254 \360\220\210\240 \a \b \f \n \r \t \v ";
3756 value = g_variant_new_string (orig);
3757 printed = g_variant_print (value, FALSE);
3758 g_variant_unref (value);
3760 g_assert_cmpstr (printed, ==, "' \\u202c \\U00010220 \\a \\b \\f \\n \\r \\t \\v '");
3761 value = g_variant_parse (NULL, printed, NULL, NULL, NULL);
3762 g_assert_cmpstr (g_variant_get_string (value, NULL), ==, orig);
3763 g_variant_unref (value);
3768 /* inf/nan strings are C99 features which Visual C++ does not support */
3769 /* inf/nan mini test */
3771 const gchar *tests[] = { "inf", "-inf", "nan" };
3774 gchar *printed_down;
3777 for (i = 0; i < G_N_ELEMENTS (tests); i++)
3779 GError *error = NULL;
3780 value = g_variant_parse (NULL, tests[i], NULL, NULL, &error);
3781 printed = g_variant_print (value, FALSE);
3782 /* Canonicalize to lowercase; https://bugzilla.gnome.org/show_bug.cgi?id=704585 */
3783 printed_down = g_ascii_strdown (printed, -1);
3784 g_assert (g_str_has_prefix (printed_down, tests[i]));
3786 g_free (printed_down);
3787 g_variant_unref (value);
3792 g_variant_type_info_assert_no_infos ();
3796 test_parse_failures (void)
3798 const gchar *test[] = {
3799 "[1, 2,", "6:", "expected value",
3800 "", "0:", "expected value",
3801 "(1, 2,", "6:", "expected value",
3802 "<1", "2:", "expected '>'",
3803 "[]", "0-2:", "unable to infer",
3804 "(,", "1:", "expected value",
3805 "[4,'']", "1-2,3-5:", "common type",
3806 "[4, '', 5]", "1-2,4-6:", "common type",
3807 "['', 4, 5]", "1-3,5-6:", "common type",
3808 "[4, 5, '']", "1-2,7-9:", "common type",
3809 "[[4], [], ['']]", "1-4,10-14:", "common type",
3810 "[[], [4], ['']]", "5-8,10-14:", "common type",
3811 "just", "4:", "expected value",
3812 "nothing", "0-7:", "unable to infer",
3813 "just [4, '']", "6-7,9-11:", "common type",
3814 "[[4,'']]", "2-3,4-6:", "common type",
3815 "([4,''],)", "2-3,4-6:", "common type",
3817 "{}", "0-2:", "unable to infer",
3818 "{[1,2],[3,4]}", "0-13:", "basic types",
3819 "{[1,2]:[3,4]}", "0-13:", "basic types",
3820 "justt", "0-5:", "unknown keyword",
3821 "nothng", "0-6:", "unknown keyword",
3822 "uint33", "0-6:", "unknown keyword",
3823 "@mi just ''", "9-11:", "can not parse as",
3824 "@ai ['']", "5-7:", "can not parse as",
3825 "@(i) ('',)", "6-8:", "can not parse as",
3826 "[[], 5]", "1-3,5-6:", "common type",
3827 "[[5], 5]", "1-4,6-7:", "common type",
3828 "5 5", "2:", "expected end of input",
3829 "[5, [5, '']]", "5-6,8-10:", "common type",
3830 "@i just 5", "3-9:", "can not parse as",
3831 "@i nothing", "3-10:", "can not parse as",
3832 "@i []", "3-5:", "can not parse as",
3833 "@i ()", "3-5:", "can not parse as",
3834 "@ai (4,)", "4-8:", "can not parse as",
3835 "@(i) []", "5-7:", "can not parse as",
3836 "(5 5)", "3:", "expected ','",
3837 "[5 5]", "3:", "expected ',' or ']'",
3838 "(5, 5 5)", "6:", "expected ',' or ')'",
3839 "[5, 5 5]", "6:", "expected ',' or ']'",
3840 "<@i []>", "4-6:", "can not parse as",
3841 "<[5 5]>", "4:", "expected ',' or ']'",
3842 "{[4,''],5}", "2-3,4-6:", "common type",
3843 "{5,[4,'']}", "4-5,6-8:", "common type",
3844 "@i {1,2}", "3-8:", "can not parse as",
3845 "{@i '', 5}", "4-6:", "can not parse as",
3846 "{5, @i ''}", "7-9:", "can not parse as",
3847 "@ai {}", "4-6:", "can not parse as",
3848 "{@i '': 5}", "4-6:", "can not parse as",
3849 "{5: @i ''}", "7-9:", "can not parse as",
3850 "{<4,5}", "3:", "expected '>'",
3851 "{4,<5}", "5:", "expected '>'",
3852 "{4,5,6}", "4:", "expected '}'",
3853 "{5 5}", "3:", "expected ':' or ','",
3854 "{4: 5: 6}", "5:", "expected ',' or '}'",
3855 "{4:5,<6:7}", "7:", "expected '>'",
3856 "{4:5,6:<7}", "9:", "expected '>'",
3857 "{4:5,6 7}", "7:", "expected ':'",
3858 "@o 'foo'", "3-8:", "object path",
3859 "@g 'zzz'", "3-8:", "signature",
3860 "@i true", "3-7:", "can not parse as",
3861 "@z 4", "0-2:", "invalid type",
3862 "@a* []", "0-3:", "definite",
3863 "@ai [3 3]", "7:", "expected ',' or ']'",
3864 "18446744073709551616", "0-20:", "too big for any type",
3865 "-18446744073709551616", "0-21:", "too big for any type",
3866 "byte 256", "5-8:", "out of range for type",
3867 "byte -1", "5-7:", "out of range for type",
3868 "int16 32768", "6-11:", "out of range for type",
3869 "int16 -32769", "6-12:", "out of range for type",
3870 "uint16 -1", "7-9:", "out of range for type",
3871 "uint16 65536", "7-12:", "out of range for type",
3872 "2147483648", "0-10:", "out of range for type",
3873 "-2147483649", "0-11:", "out of range for type",
3874 "uint32 -1", "7-9:", "out of range for type",
3875 "uint32 4294967296", "7-17:", "out of range for type",
3876 "@x 9223372036854775808", "3-22:", "out of range for type",
3877 "@x -9223372036854775809", "3-23:", "out of range for type",
3878 "@t -1", "3-5:", "out of range for type",
3879 "@t 18446744073709551616", "3-23:", "too big for any type",
3880 "handle 2147483648", "7-17:", "out of range for type",
3881 "handle -2147483649", "7-18:", "out of range for type",
3882 "1.798e308", "0-9:", "too big for any type",
3883 "37.5a488", "4-5:", "invalid character",
3884 "0x7ffgf", "5-6:", "invalid character",
3885 "07758", "4-5:", "invalid character",
3886 "123a5", "3-4:", "invalid character",
3887 "@ai 123", "4-7:", "can not parse as",
3888 "'\"\\'", "0-4:", "unterminated string",
3889 "'\"\\'\\", "0-5:", "unterminated string",
3890 "boolean 4", "8-9:", "can not parse as",
3891 "int32 true", "6-10:", "can not parse as",
3892 "[double 5, int32 5]", "1-9,11-18:", "common type",
3893 "string 4", "7-8:", "can not parse as"
3897 for (i = 0; i < G_N_ELEMENTS (test); i += 3)
3899 GError *error = NULL;
3902 value = g_variant_parse (NULL, test[i], NULL, NULL, &error);
3903 g_assert (value == NULL);
3905 if (!strstr (error->message, test[i+2]))
3906 g_error ("test %d: Can't find '%s' in '%s'", i / 3,
3907 test[i+2], error->message);
3909 if (!g_str_has_prefix (error->message, test[i+1]))
3910 g_error ("test %d: Expected location '%s' in '%s'", i / 3,
3911 test[i+1], error->message);
3913 g_error_free (error);
3918 test_parse_bad_format_char (void)
3920 g_variant_new_parsed ("%z");
3922 g_assert_not_reached ();
3926 test_parse_bad_format_string (void)
3928 g_variant_new_parsed ("uint32 %i", 2);
3930 g_assert_not_reached ();
3934 test_parse_bad_args (void)
3936 g_variant_new_parsed ("%@i", g_variant_new_uint32 (2));
3938 g_assert_not_reached ();
3942 test_parse_positional (void)
3945 check_and_free (g_variant_new_parsed ("[('one', 1), (%s, 2),"
3946 " ('three', %i)]", "two", 3),
3947 "[('one', 1), ('two', 2), ('three', 3)]");
3948 value = g_variant_new_parsed ("[('one', 1), (%s, 2),"
3949 " ('three', %u)]", "two", 3);
3950 g_assert (g_variant_is_of_type (value, G_VARIANT_TYPE ("a(su)")));
3951 check_and_free (value, "[('one', 1), ('two', 2), ('three', 3)]");
3952 check_and_free (g_variant_new_parsed ("{%s:%i}", "one", 1), "{'one': 1}");
3954 if (g_test_undefined ())
3956 do_failed_test ("/gvariant/parse/subprocess/bad-format-char",
3957 "*GVariant format string*");
3959 do_failed_test ("/gvariant/parse/subprocess/bad-format-string",
3960 "*can not parse as*");
3962 do_failed_test ("/gvariant/parse/subprocess/bad-args",
3963 "*expected GVariant of type 'i'*");
3968 test_floating (void)
3972 value = g_variant_new_int32 (42);
3973 g_assert (g_variant_is_floating (value));
3974 g_variant_ref_sink (value);
3975 g_assert (!g_variant_is_floating (value));
3976 g_variant_unref (value);
3980 test_bytestring (void)
3982 const gchar *test_string = "foo,bar,baz,quux,\xffoooo";
3986 const gchar *const_str;
3987 GVariant *untrusted_empty;
3989 strv = g_strsplit (test_string, ",", 0);
3991 value = g_variant_new_bytestring_array ((const gchar **) strv, -1);
3992 g_assert (g_variant_is_floating (value));
3995 str = g_variant_print (value, FALSE);
3996 g_variant_unref (value);
3998 value = g_variant_parse (NULL, str, NULL, NULL, NULL);
4001 strv = g_variant_dup_bytestring_array (value, NULL);
4002 g_variant_unref (value);
4004 str = g_strjoinv (",", strv);
4007 g_assert_cmpstr (str, ==, test_string);
4010 strv = g_strsplit (test_string, ",", 0);
4011 value = g_variant_new ("(^aay^a&ay^ay^&ay)",
4012 strv, strv, strv[0], strv[0]);
4015 g_variant_get_child (value, 0, "^a&ay", &strv);
4016 str = g_strjoinv (",", strv);
4018 g_assert_cmpstr (str, ==, test_string);
4021 g_variant_get_child (value, 0, "^aay", &strv);
4022 str = g_strjoinv (",", strv);
4024 g_assert_cmpstr (str, ==, test_string);
4027 g_variant_get_child (value, 1, "^a&ay", &strv);
4028 str = g_strjoinv (",", strv);
4030 g_assert_cmpstr (str, ==, test_string);
4033 g_variant_get_child (value, 1, "^aay", &strv);
4034 str = g_strjoinv (",", strv);
4036 g_assert_cmpstr (str, ==, test_string);
4039 g_variant_get_child (value, 2, "^ay", &str);
4040 g_assert_cmpstr (str, ==, "foo");
4043 g_variant_get_child (value, 2, "^&ay", &str);
4044 g_assert_cmpstr (str, ==, "foo");
4046 g_variant_get_child (value, 3, "^ay", &str);
4047 g_assert_cmpstr (str, ==, "foo");
4050 g_variant_get_child (value, 3, "^&ay", &str);
4051 g_assert_cmpstr (str, ==, "foo");
4052 g_variant_unref (value);
4054 untrusted_empty = g_variant_new_from_data (G_VARIANT_TYPE ("ay"), NULL, 0, FALSE, NULL, NULL);
4055 value = g_variant_get_normal_form (untrusted_empty);
4056 const_str = g_variant_get_bytestring (value);
4058 g_variant_unref (value);
4059 g_variant_unref (untrusted_empty);
4063 test_lookup_value (void)
4066 const gchar *dict, *key, *value;
4068 { "@a{ss} {'x': 'y'}", "x", "'y'" },
4069 { "@a{ss} {'x': 'y'}", "y" },
4070 { "@a{os} {'/x': 'y'}", "/x", "'y'" },
4071 { "@a{os} {'/x': 'y'}", "/y" },
4072 { "@a{sv} {'x': <'y'>}", "x", "'y'" },
4073 { "@a{sv} {'x': <5>}", "x", "5" },
4074 { "@a{sv} {'x': <'y'>}", "y" }
4078 for (i = 0; i < G_N_ELEMENTS (cases); i++)
4080 GVariant *dictionary;
4084 dictionary = g_variant_parse (NULL, cases[i].dict, NULL, NULL, NULL);
4085 value = g_variant_lookup_value (dictionary, cases[i].key, NULL);
4086 g_variant_unref (dictionary);
4088 if (value == NULL && cases[i].value == NULL)
4091 g_assert (value && cases[i].value);
4092 p = g_variant_print (value, FALSE);
4093 g_assert_cmpstr (cases[i].value, ==, p);
4094 g_variant_unref (value);
4107 dict = g_variant_parse (NULL,
4108 "{'a': <5>, 'b': <'c'>}",
4111 ok = g_variant_lookup (dict, "a", "i", &num);
4113 g_assert_cmpint (num, ==, 5);
4115 ok = g_variant_lookup (dict, "a", "&s", &str);
4118 ok = g_variant_lookup (dict, "q", "&s", &str);
4121 ok = g_variant_lookup (dict, "b", "i", &num);
4124 ok = g_variant_lookup (dict, "b", "&s", &str);
4126 g_assert_cmpstr (str, ==, "c");
4128 ok = g_variant_lookup (dict, "q", "&s", &str);
4131 g_variant_unref (dict);
4135 untrusted (GVariant *a)
4138 const GVariantType *type;
4141 type = g_variant_get_type (a);
4142 bytes = g_variant_get_data_as_bytes (a);
4143 b = g_variant_new_from_bytes (type, bytes, FALSE);
4144 g_bytes_unref (bytes);
4145 g_variant_unref (a);
4156 a = untrusted (g_variant_new_byte (5));
4157 b = g_variant_new_byte (6);
4158 g_assert (g_variant_compare (a, b) < 0);
4159 g_variant_unref (a);
4160 g_variant_unref (b);
4161 a = untrusted (g_variant_new_int16 (G_MININT16));
4162 b = g_variant_new_int16 (G_MAXINT16);
4163 g_assert (g_variant_compare (a, b) < 0);
4164 g_variant_unref (a);
4165 g_variant_unref (b);
4166 a = untrusted (g_variant_new_uint16 (0));
4167 b = g_variant_new_uint16 (G_MAXUINT16);
4168 g_assert (g_variant_compare (a, b) < 0);
4169 g_variant_unref (a);
4170 g_variant_unref (b);
4171 a = untrusted (g_variant_new_int32 (G_MININT32));
4172 b = g_variant_new_int32 (G_MAXINT32);
4173 g_assert (g_variant_compare (a, b) < 0);
4174 g_variant_unref (a);
4175 g_variant_unref (b);
4176 a = untrusted (g_variant_new_uint32 (0));
4177 b = g_variant_new_uint32 (G_MAXUINT32);
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_int64 (G_MININT64));
4182 b = g_variant_new_int64 (G_MAXINT64);
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_uint64 (0));
4187 b = g_variant_new_uint64 (G_MAXUINT64);
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_double (G_MINDOUBLE));
4192 b = g_variant_new_double (G_MAXDOUBLE);
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_string ("abc"));
4197 b = g_variant_new_string ("abd");
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_object_path ("/abc"));
4202 b = g_variant_new_object_path ("/abd");
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_signature ("g"));
4207 b = g_variant_new_signature ("o");
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_boolean (FALSE));
4212 b = g_variant_new_boolean (TRUE);
4213 g_assert (g_variant_compare (a, b) < 0);
4214 g_variant_unref (a);
4215 g_variant_unref (b);
4224 a = untrusted (g_variant_new_byte (5));
4225 b = g_variant_get_normal_form (a);
4226 g_assert (g_variant_equal (a, b));
4227 g_variant_unref (a);
4228 g_variant_unref (b);
4229 a = untrusted (g_variant_new_int16 (G_MININT16));
4230 b = g_variant_get_normal_form (a);
4231 g_assert (g_variant_equal (a, b));
4232 g_variant_unref (a);
4233 g_variant_unref (b);
4234 a = untrusted (g_variant_new_uint16 (0));
4235 b = g_variant_get_normal_form (a);
4236 g_assert (g_variant_equal (a, b));
4237 g_variant_unref (a);
4238 g_variant_unref (b);
4239 a = untrusted (g_variant_new_int32 (G_MININT32));
4240 b = g_variant_get_normal_form (a);
4241 g_assert (g_variant_equal (a, b));
4242 g_variant_unref (a);
4243 g_variant_unref (b);
4244 a = untrusted (g_variant_new_uint32 (0));
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_int64 (G_MININT64));
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_uint64 (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_double (G_MINDOUBLE));
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_string ("abc"));
4265 g_assert (g_variant_equal (a, a));
4266 b = g_variant_get_normal_form (a);
4267 g_assert (g_variant_equal (a, b));
4268 g_variant_unref (a);
4269 g_variant_unref (b);
4270 a = untrusted (g_variant_new_object_path ("/abc"));
4271 g_assert (g_variant_equal (a, a));
4272 b = g_variant_get_normal_form (a);
4274 g_assert (g_variant_equal (a, b));
4275 g_variant_unref (a);
4276 g_variant_unref (b);
4277 a = untrusted (g_variant_new_signature ("g"));
4278 g_assert (g_variant_equal (a, a));
4279 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_boolean (FALSE));
4285 b = g_variant_get_normal_form (a);
4286 g_assert (g_variant_equal (a, b));
4287 g_variant_unref (a);
4288 g_variant_unref (b);
4292 test_fixed_array (void)
4301 a = g_variant_new_parsed ("[1,2,3,4,5]");
4302 elts = g_variant_get_fixed_array (a, &n_elts, sizeof (gint32));
4303 g_assert (n_elts == 5);
4304 for (i = 0; i < 5; i++)
4305 g_assert_cmpint (elts[i], ==, i + 1);
4306 g_variant_unref (a);
4309 for (i = 0; i < 5; i++)
4311 a = g_variant_new_fixed_array (G_VARIANT_TYPE_INT32, values,
4312 G_N_ELEMENTS (values), sizeof (values[0]));
4313 g_assert_cmpstr (g_variant_get_type_string (a), ==, "ai");
4314 elts = g_variant_get_fixed_array (a, &n_elts, sizeof (gint32));
4315 g_assert (n_elts == 5);
4316 for (i = 0; i < 5; i++)
4317 g_assert_cmpint (elts[i], ==, i + 1);
4318 g_variant_unref (a);
4322 test_check_format_string (void)
4326 value = g_variant_new ("(sas)", "foo", NULL);
4327 g_variant_ref_sink (value);
4329 g_assert (g_variant_check_format_string (value, "(s*)", TRUE));
4330 g_assert (g_variant_check_format_string (value, "(s*)", FALSE));
4331 g_assert (!g_variant_check_format_string (value, "(u*)", TRUE));
4332 g_assert (!g_variant_check_format_string (value, "(u*)", FALSE));
4334 g_assert (g_variant_check_format_string (value, "(&s*)", FALSE));
4335 g_test_expect_message ("GLib", G_LOG_LEVEL_CRITICAL, "*contains a '&' character*");
4336 g_assert (!g_variant_check_format_string (value, "(&s*)", TRUE));
4337 g_test_assert_expected_messages ();
4339 g_assert (g_variant_check_format_string (value, "(s^as)", TRUE));
4340 g_assert (g_variant_check_format_string (value, "(s^as)", FALSE));
4342 g_test_expect_message ("GLib", G_LOG_LEVEL_CRITICAL, "*contains a '&' character*");
4343 g_assert (!g_variant_check_format_string (value, "(s^a&s)", TRUE));
4344 g_test_assert_expected_messages ();
4345 g_assert (g_variant_check_format_string (value, "(s^a&s)", FALSE));
4347 g_variant_unref (value);
4349 /* Do it again with a type that will let us put a '&' after a '^' */
4350 value = g_variant_new ("(say)", "foo", NULL);
4351 g_variant_ref_sink (value);
4353 g_assert (g_variant_check_format_string (value, "(s*)", TRUE));
4354 g_assert (g_variant_check_format_string (value, "(s*)", FALSE));
4355 g_assert (!g_variant_check_format_string (value, "(u*)", TRUE));
4356 g_assert (!g_variant_check_format_string (value, "(u*)", FALSE));
4358 g_assert (g_variant_check_format_string (value, "(&s*)", FALSE));
4359 g_test_expect_message ("GLib", G_LOG_LEVEL_CRITICAL, "*contains a '&' character*");
4360 g_assert (!g_variant_check_format_string (value, "(&s*)", TRUE));
4361 g_test_assert_expected_messages ();
4363 g_assert (g_variant_check_format_string (value, "(s^ay)", TRUE));
4364 g_assert (g_variant_check_format_string (value, "(s^ay)", FALSE));
4366 g_test_expect_message ("GLib", G_LOG_LEVEL_CRITICAL, "*contains a '&' character*");
4367 g_assert (!g_variant_check_format_string (value, "(s^&ay)", TRUE));
4368 g_test_assert_expected_messages ();
4369 g_assert (g_variant_check_format_string (value, "(s^&ay)", FALSE));
4371 g_assert (g_variant_check_format_string (value, "r", FALSE));
4372 g_assert (g_variant_check_format_string (value, "(?a?)", FALSE));
4374 g_variant_unref (value);
4378 verify_gvariant_checksum (const gchar *sha256,
4383 checksum = g_compute_checksum_for_data (G_CHECKSUM_SHA256,
4384 g_variant_get_data (v),
4385 g_variant_get_size (v));
4386 g_assert_cmpstr (sha256, ==, checksum);
4391 verify_gvariant_checksum_va (const gchar *sha256,
4398 va_start (args, fmt);
4400 v = g_variant_new_va (fmt, NULL, &args);
4401 g_variant_ref_sink (v);
4402 #if G_BYTE_ORDER == G_BIG_ENDIAN
4404 GVariant *byteswapped = g_variant_byteswap (v);
4405 g_variant_unref (v);
4412 verify_gvariant_checksum (sha256, v);
4414 g_variant_unref (v);
4418 test_checksum_basic (void)
4420 verify_gvariant_checksum_va ("e8a4b2ee7ede79a3afb332b5b6cc3d952a65fd8cffb897f5d18016577c33d7cc",
4422 verify_gvariant_checksum_va ("c53e363c33b00cfce298229ee83856b8a98c2e6126cab13f65899f62473b0df5",
4424 verify_gvariant_checksum_va ("2b4c342f5433ebe591a1da77e013d1b72475562d48578dca8b84bac6651c3cb9",
4426 verify_gvariant_checksum_va ("12a3ae445661ce5dee78d0650d33362dec29c4f82af05e7e57fb595bbbacf0ca",
4428 verify_gvariant_checksum_va ("e25a59b24440eb6c833aa79c93b9840e6eab6966add0dacf31df7e9e7000f5b3",
4430 verify_gvariant_checksum_va ("4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a",
4432 verify_gvariant_checksum_va ("ca2fd00fa001190744c15c317643ab092e7048ce086a243e2be9437c898de1bb",
4437 test_checksum_nested (void)
4439 static const char* const strv[] = {"foo", "bar", "baz", NULL};
4441 verify_gvariant_checksum_va ("31fbc92f08fddaca716188fe4b5d44ae122fc6306fd3c6925af53cfa47ea596d",
4443 verify_gvariant_checksum_va ("01759d683cead856d1d386d59af0578841698a424a265345ad5413122f220de8",
4444 "(su)", "moocow", 79);
4445 verify_gvariant_checksum_va ("52b3ae95f19b3e642ea1d01185aea14a09004c1d1712672644427403a8a0afe6",
4446 "(qyst)", G_MAXUINT16, 9, "moocow", G_MAXUINT64);
4447 verify_gvariant_checksum_va ("6fc6f4524161c3ae0d316812d7088e3fcd372023edaea2d7821093be40ae1060",
4448 "(@ay)", g_variant_new_bytestring ("\xFF\xFF\xFF"));
4449 verify_gvariant_checksum_va ("572aca386e1a983dd23bb6eb6e3dfa72eef9ca7c7744581aa800e18d7d9d0b0b",
4451 verify_gvariant_checksum_va ("4bddf6174c791bb44fc6a4106573031690064df34b741033a0122ed8dc05bcf3",
4452 "(yvu)", 254, g_variant_new ("(^as)", strv), 42);
4462 const guint8 values[5] = { 1, 2, 3, 4, 5 };
4467 bytes = g_bytes_new (&values, 5);
4468 a = g_variant_new_from_bytes (G_VARIANT_TYPE_BYTESTRING, bytes, TRUE);
4469 g_bytes_unref (bytes);
4471 elts = g_variant_get_fixed_array (a, &n_elts, sizeof (guint8));
4472 g_assert (n_elts == 5);
4473 for (i = 0; i < 5; i++)
4474 g_assert_cmpint (elts[i], ==, i + 1);
4476 bytes2 = g_variant_get_data_as_bytes (a);
4477 g_variant_unref (a);
4479 bytes = g_bytes_new (&values, 5);
4480 g_assert (g_bytes_equal (bytes, bytes2));
4481 g_bytes_unref (bytes);
4482 g_bytes_unref (bytes2);
4484 tuple = g_variant_new_parsed ("['foo', 'bar']");
4485 bytes = g_variant_get_data_as_bytes (tuple); /* force serialisation */
4486 a = g_variant_get_child_value (tuple, 1);
4487 bytes2 = g_variant_get_data_as_bytes (a);
4488 g_assert (!g_bytes_equal (bytes, bytes2));
4490 g_bytes_unref (bytes);
4491 g_bytes_unref (bytes2);
4492 g_variant_unref (a);
4493 g_variant_unref (tuple);
4497 const GVariantType *type;
4503 test_print_context (void)
4505 ContextTest tests[] = {
4506 { NULL, "(1, 2, 3, 'abc", " ^^^^" },
4507 { NULL, "[1, 2, 3, 'str']", " ^ ^^^^^" },
4508 { G_VARIANT_TYPE_UINT16, "{ 'abc':'def' }", " ^^^^^^^^^^^^^^^" },
4509 { NULL, "<5", " ^" },
4510 { NULL, "'ab\\ux'", " ^^^^^^^" },
4511 { NULL, "'ab\\U00efx'", " ^^^^^^^^^^^" }
4516 GError *error = NULL;
4518 for (i = 0; i < G_N_ELEMENTS (tests); i++)
4520 v = g_variant_parse (tests[i].type, tests[i].in, NULL, NULL, &error);
4522 s = g_variant_parse_error_print_context (error, tests[i].in);
4523 g_assert (strstr (s, tests[i].out) != NULL);
4525 g_clear_error (&error);
4530 test_error_quark (void)
4532 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
4533 g_assert (g_variant_parser_get_error_quark () == g_variant_parse_error_quark ());
4534 G_GNUC_END_IGNORE_DEPRECATIONS
4538 main (int argc, char **argv)
4542 g_test_init (&argc, &argv, NULL);
4544 g_test_add_func ("/gvariant/type", test_gvarianttype);
4545 g_test_add_func ("/gvariant/typeinfo", test_gvarianttypeinfo);
4546 g_test_add_func ("/gvariant/serialiser/maybe", test_maybes);
4547 g_test_add_func ("/gvariant/serialiser/array", test_arrays);
4548 g_test_add_func ("/gvariant/serialiser/tuple", test_tuples);
4549 g_test_add_func ("/gvariant/serialiser/variant", test_variants);
4550 g_test_add_func ("/gvariant/serialiser/strings", test_strings);
4551 g_test_add_func ("/gvariant/serialiser/byteswap", test_byteswaps);
4553 for (i = 1; i <= 20; i += 4)
4557 testname = g_strdup_printf ("/gvariant/serialiser/fuzz/%d%%", i);
4558 g_test_add_data_func (testname, GINT_TO_POINTER (i),
4559 (gpointer) test_fuzzes);
4563 g_test_add_func ("/gvariant/string", test_string);
4564 g_test_add_func ("/gvariant/utf8", test_utf8);
4565 g_test_add_func ("/gvariant/containers", test_containers);
4566 g_test_add_func ("/gvariant/format-strings", test_format_strings);
4567 g_test_add_func ("/gvariant/invalid-varargs", test_invalid_varargs);
4568 g_test_add_func ("/gvariant/varargs", test_varargs);
4569 g_test_add_func ("/gvariant/varargs/subprocess/empty-array", test_varargs_empty_array);
4570 g_test_add_func ("/gvariant/valist", test_valist);
4571 g_test_add_func ("/gvariant/builder-memory", test_builder_memory);
4572 g_test_add_func ("/gvariant/hashing", test_hashing);
4573 g_test_add_func ("/gvariant/byteswap", test_gv_byteswap);
4574 g_test_add_func ("/gvariant/parser", test_parses);
4575 g_test_add_func ("/gvariant/parse-failures", test_parse_failures);
4576 g_test_add_func ("/gvariant/parse-positional", test_parse_positional);
4577 g_test_add_func ("/gvariant/parse/subprocess/bad-format-char", test_parse_bad_format_char);
4578 g_test_add_func ("/gvariant/parse/subprocess/bad-format-string", test_parse_bad_format_string);
4579 g_test_add_func ("/gvariant/parse/subprocess/bad-args", test_parse_bad_args);
4580 g_test_add_func ("/gvariant/floating", test_floating);
4581 g_test_add_func ("/gvariant/bytestring", test_bytestring);
4582 g_test_add_func ("/gvariant/lookup-value", test_lookup_value);
4583 g_test_add_func ("/gvariant/lookup", test_lookup);
4584 g_test_add_func ("/gvariant/compare", test_compare);
4585 g_test_add_func ("/gvariant/equal", test_equal);
4586 g_test_add_func ("/gvariant/fixed-array", test_fixed_array);
4587 g_test_add_func ("/gvariant/check-format-string", test_check_format_string);
4589 g_test_add_func ("/gvariant/checksum-basic", test_checksum_basic);
4590 g_test_add_func ("/gvariant/checksum-nested", test_checksum_nested);
4592 g_test_add_func ("/gvariant/gbytes", test_gbytes);
4593 g_test_add_func ("/gvariant/print-context", test_print_context);
4594 g_test_add_func ("/gvariant/error-quark", test_error_quark);
4596 return g_test_run ();