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 g_assert (memcmp (serialised.data, data, serialised.size) == 0);
1524 g_assert (g_variant_serialised_n_children (serialised) == n_children);
1526 for (i = 0; i < n_children; i++)
1528 GVariantSerialised child;
1530 child = g_variant_serialised_get_child (serialised, i);
1531 g_assert (child.type_info == instances[i]->type_info);
1532 random_instance_assert (instances[i], child.data, child.size);
1533 g_variant_type_info_unref (child.type_info);
1536 flavoured_free (serialised.data, flavour);
1543 for (i = 0; i < n_children; i++)
1544 random_instance_free (instances[i]);
1548 g_variant_type_info_unref (element_info);
1549 g_variant_type_info_unref (array_info);
1558 for (i = 0; i < 100; i++)
1561 g_variant_type_info_assert_no_infos ();
1567 GVariantTypeInfo *type_info;
1568 RandomInstance **instances;
1569 gboolean fixed_size;
1576 n_children = g_test_rand_int_range (0, MAX_TUPLE_CHILDREN);
1577 instances = g_new (RandomInstance *, n_children);
1580 GString *type_string;
1586 type_string = g_string_new ("(");
1587 for (i = 0; i < n_children; i++)
1591 instances[i] = random_instance (NULL);
1593 alignment |= instances[i]->alignment;
1594 if (!instances[i]->is_fixed_sized)
1597 str = g_variant_type_info_get_type_string (instances[i]->type_info);
1598 g_string_append (type_string, str);
1600 g_string_append_c (type_string, ')');
1602 type_info = g_variant_type_info_get (G_VARIANT_TYPE (type_string->str));
1603 g_string_free (type_string, TRUE);
1606 needed_size = g_variant_serialiser_needed_size (type_info,
1607 random_instance_filler,
1608 (gpointer *) instances,
1611 gsize body_size = 0;
1615 for (i = 0; i < n_children; i++)
1617 append_instance_size (instances[i], &body_size);
1619 if (i != n_children - 1 && !instances[i]->is_fixed_sized)
1625 body_size += (-body_size) & alignment;
1627 g_assert ((body_size == 0) == (n_children == 0));
1628 if (n_children == 0)
1632 offset_size = calculate_offset_size (body_size, offsets);
1633 g_assert_cmpint (needed_size, ==, body_size + offsets * offset_size);
1641 body_ptr = data = align_malloc (needed_size);
1642 ofs_ptr = body_ptr + needed_size;
1644 for (i = 0; i < n_children; i++)
1646 append_instance_data (instances[i], &body_ptr);
1648 if (i != n_children - 1 && !instances[i]->is_fixed_sized)
1649 prepend_offset (&ofs_ptr, body_ptr - data, offset_size);
1654 while (((gsize) body_ptr) & alignment)
1657 g_assert ((body_ptr == data) == (n_children == 0));
1658 if (n_children == 0)
1664 g_assert (body_ptr == ofs_ptr);
1671 alignment = (alignment & ALIGN_BITS) + 1;
1673 for (flavour = 0; flavour < 8; flavour += alignment)
1675 GVariantSerialised serialised;
1677 serialised.type_info = type_info;
1678 serialised.data = flavoured_malloc (needed_size, flavour);
1679 serialised.size = needed_size;
1681 g_variant_serialiser_serialise (serialised, random_instance_filler,
1682 (gpointer *) instances, n_children);
1684 g_assert (memcmp (serialised.data, data, serialised.size) == 0);
1685 g_assert (g_variant_serialised_n_children (serialised) == n_children);
1687 for (i = 0; i < n_children; i++)
1689 GVariantSerialised child;
1691 child = g_variant_serialised_get_child (serialised, i);
1692 g_assert (child.type_info == instances[i]->type_info);
1693 random_instance_assert (instances[i], child.data, child.size);
1694 g_variant_type_info_unref (child.type_info);
1697 flavoured_free (serialised.data, flavour);
1704 for (i = 0; i < n_children; i++)
1705 random_instance_free (instances[i]);
1709 g_variant_type_info_unref (type_info);
1718 for (i = 0; i < 100; i++)
1721 g_variant_type_info_assert_no_infos ();
1727 GVariantTypeInfo *type_info;
1728 RandomInstance *instance;
1729 const gchar *type_string;
1734 type_info = g_variant_type_info_get (G_VARIANT_TYPE_VARIANT);
1735 instance = random_instance (NULL);
1737 type_string = g_variant_type_info_get_type_string (instance->type_info);
1738 len = strlen (type_string);
1740 needed_size = g_variant_serialiser_needed_size (type_info,
1741 random_instance_filler,
1742 (gpointer *) &instance, 1);
1744 g_assert_cmpint (needed_size, ==, instance->size + 1 + len);
1749 ptr = data = align_malloc (needed_size);
1750 append_instance_data (instance, &ptr);
1752 memcpy (ptr, type_string, len);
1755 g_assert (data + needed_size == ptr);
1762 /* variants are always 8-aligned */
1763 alignment = ALIGN_BITS + 1;
1765 for (flavour = 0; flavour < 8; flavour += alignment)
1767 GVariantSerialised serialised;
1768 GVariantSerialised child;
1770 serialised.type_info = type_info;
1771 serialised.data = flavoured_malloc (needed_size, flavour);
1772 serialised.size = needed_size;
1774 g_variant_serialiser_serialise (serialised, random_instance_filler,
1775 (gpointer *) &instance, 1);
1777 g_assert (memcmp (serialised.data, data, serialised.size) == 0);
1778 g_assert (g_variant_serialised_n_children (serialised) == 1);
1780 child = g_variant_serialised_get_child (serialised, 0);
1781 g_assert (child.type_info == instance->type_info);
1782 random_instance_check (instance, child.data, child.size);
1784 g_variant_type_info_unref (child.type_info);
1785 flavoured_free (serialised.data, flavour);
1789 g_variant_type_info_unref (type_info);
1790 random_instance_free (instance);
1795 test_variants (void)
1799 for (i = 0; i < 100; i++)
1802 g_variant_type_info_assert_no_infos ();
1815 #define is_objpath is_string | 2
1816 #define is_sig is_string | 4
1818 { is_nval, 0, NULL },
1819 { is_nval, 13, "hello\xffworld!" },
1820 { is_string, 13, "hello world!" },
1821 { is_nval, 13, "hello world\0" },
1822 { is_nval, 13, "hello\0world!" },
1823 { is_nval, 12, "hello world!" },
1824 { is_nval, 13, "hello world!\xff" },
1826 { is_objpath, 2, "/" },
1827 { is_objpath, 3, "/a" },
1828 { is_string, 3, "//" },
1829 { is_objpath, 11, "/some/path" },
1830 { is_string, 12, "/some/path/" },
1831 { is_nval, 11, "/some\0path" },
1832 { is_string, 11, "/some\\path" },
1833 { is_string, 12, "/some//path" },
1834 { is_string, 12, "/some-/path" },
1838 { is_sig, 5, "(si)" },
1839 { is_string, 4, "(si" },
1840 { is_string, 2, "*" },
1841 { is_sig, 3, "ai" },
1842 { is_string, 3, "mi" },
1843 { is_string, 2, "r" },
1844 { is_sig, 15, "(yyy{sv}ssiai)" },
1845 { is_string, 16, "(yyy{yv}ssiai))" },
1846 { is_string, 15, "(yyy{vv}ssiai)" },
1847 { is_string, 15, "(yyy{sv)ssiai}" }
1851 for (i = 0; i < G_N_ELEMENTS (test_cases); i++)
1855 flags = g_variant_serialiser_is_string (test_cases[i].data,
1859 flags |= g_variant_serialiser_is_object_path (test_cases[i].data,
1863 flags |= g_variant_serialiser_is_signature (test_cases[i].data,
1867 g_assert (flags == test_cases[i].flags);
1871 typedef struct _TreeInstance TreeInstance;
1872 struct _TreeInstance
1874 GVariantTypeInfo *info;
1876 TreeInstance **children;
1887 static GVariantType *
1888 make_random_definite_type (int depth)
1890 GString *description;
1891 GString *type_string;
1894 description = g_string_new (NULL);
1895 type_string = g_string_new (NULL);
1896 type = append_type_string (type_string, description, TRUE, depth);
1897 g_string_free (description, TRUE);
1898 g_string_free (type_string, TRUE);
1904 make_random_string (gchar *string,
1906 const GVariantType *type)
1910 /* create strings that are valid signature strings */
1911 #define good_chars "bynqiuxthdsog"
1913 for (i = 0; i < size - 1; i++)
1914 string[i] = good_chars[g_test_rand_int_range (0, strlen (good_chars))];
1917 /* in case we need an object path, prefix a '/' */
1918 if (*g_variant_type_peek_string (type) == 'o')
1924 static TreeInstance *
1925 tree_instance_new (const GVariantType *type,
1928 const GVariantType *child_type = NULL;
1929 GVariantType *mytype = NULL;
1930 TreeInstance *instance;
1931 gboolean is_tuple_type;
1934 type = mytype = make_random_definite_type (depth);
1936 instance = g_slice_new (TreeInstance);
1937 instance->info = g_variant_type_info_get (type);
1938 instance->children = NULL;
1939 instance->n_children = 0;
1940 instance->data_size = 0;
1942 is_tuple_type = FALSE;
1944 switch (*g_variant_type_peek_string (type))
1946 case G_VARIANT_TYPE_INFO_CHAR_MAYBE:
1947 instance->n_children = g_test_rand_int_range (0, 2);
1948 child_type = g_variant_type_element (type);
1951 case G_VARIANT_TYPE_INFO_CHAR_ARRAY:
1952 instance->n_children = g_test_rand_int_range (0, MAX_ARRAY_CHILDREN);
1953 child_type = g_variant_type_element (type);
1956 case G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY:
1957 case G_VARIANT_TYPE_INFO_CHAR_TUPLE:
1958 instance->n_children = g_variant_type_n_items (type);
1959 child_type = g_variant_type_first (type);
1960 is_tuple_type = TRUE;
1963 case G_VARIANT_TYPE_INFO_CHAR_VARIANT:
1964 instance->n_children = 1;
1969 instance->data.integer = g_test_rand_int_range (0, 2);
1970 instance->data_size = 1;
1974 instance->data.integer = g_test_rand_int ();
1975 instance->data_size = 1;
1979 instance->data.integer = g_test_rand_int ();
1980 instance->data_size = 2;
1983 case 'i': case 'u': case 'h':
1984 instance->data.integer = g_test_rand_int ();
1985 instance->data_size = 4;
1989 instance->data.integer = g_test_rand_int ();
1990 instance->data.integer <<= 32;
1991 instance->data.integer |= (guint32) g_test_rand_int ();
1992 instance->data_size = 8;
1996 instance->data.floating = g_test_rand_double ();
1997 instance->data_size = 8;
2000 case 's': case 'o': case 'g':
2001 instance->data_size = g_test_rand_int_range (10, 20);
2002 make_random_string (instance->data.string, instance->data_size, type);
2006 if (instance->data_size == 0)
2007 /* no data -> it is a container */
2011 instance->children = g_new (TreeInstance *, instance->n_children);
2013 for (i = 0; i < instance->n_children; i++)
2015 instance->children[i] = tree_instance_new (child_type, depth - 1);
2018 child_type = g_variant_type_next (child_type);
2021 g_assert (!is_tuple_type || child_type == NULL);
2024 g_variant_type_free (mytype);
2030 tree_instance_free (TreeInstance *instance)
2034 g_variant_type_info_unref (instance->info);
2035 for (i = 0; i < instance->n_children; i++)
2036 tree_instance_free (instance->children[i]);
2037 g_free (instance->children);
2038 g_slice_free (TreeInstance, instance);
2041 static gboolean i_am_writing_byteswapped;
2044 tree_filler (GVariantSerialised *serialised,
2047 TreeInstance *instance = data;
2049 if (serialised->type_info == NULL)
2050 serialised->type_info = instance->info;
2052 if (instance->data_size == 0)
2053 /* is a container */
2055 if (serialised->size == 0)
2057 g_variant_serialiser_needed_size (instance->info, tree_filler,
2058 (gpointer *) instance->children,
2059 instance->n_children);
2061 if (serialised->data)
2062 g_variant_serialiser_serialise (*serialised, tree_filler,
2063 (gpointer *) instance->children,
2064 instance->n_children);
2069 if (serialised->size == 0)
2070 serialised->size = instance->data_size;
2072 if (serialised->data)
2074 switch (instance->data_size)
2077 *serialised->data = instance->data.integer;
2082 guint16 value = instance->data.integer;
2084 if (i_am_writing_byteswapped)
2085 value = GUINT16_SWAP_LE_BE (value);
2087 *(guint16 *) serialised->data = value;
2093 guint32 value = instance->data.integer;
2095 if (i_am_writing_byteswapped)
2096 value = GUINT32_SWAP_LE_BE (value);
2098 *(guint32 *) serialised->data = value;
2104 guint64 value = instance->data.integer;
2106 if (i_am_writing_byteswapped)
2107 value = GUINT64_SWAP_LE_BE (value);
2109 *(guint64 *) serialised->data = value;
2114 memcpy (serialised->data,
2115 instance->data.string,
2116 instance->data_size);
2124 check_tree (TreeInstance *instance,
2125 GVariantSerialised serialised)
2127 if (instance->info != serialised.type_info)
2130 if (instance->data_size == 0)
2131 /* is a container */
2135 if (g_variant_serialised_n_children (serialised) !=
2136 instance->n_children)
2139 for (i = 0; i < instance->n_children; i++)
2141 GVariantSerialised child;
2142 gpointer data = NULL;
2145 child = g_variant_serialised_get_child (serialised, i);
2146 if (child.size && child.data == NULL)
2147 child.data = data = g_malloc0 (child.size);
2148 ok = check_tree (instance->children[i], child);
2149 g_variant_type_info_unref (child.type_info);
2161 switch (instance->data_size)
2164 g_assert (serialised.size == 1);
2165 return *(guint8 *) serialised.data ==
2166 (guint8) instance->data.integer;
2169 g_assert (serialised.size == 2);
2170 return *(guint16 *) serialised.data ==
2171 (guint16) instance->data.integer;
2174 g_assert (serialised.size == 4);
2175 return *(guint32 *) serialised.data ==
2176 (guint32) instance->data.integer;
2179 g_assert (serialised.size == 8);
2180 return *(guint64 *) serialised.data ==
2181 (guint64) instance->data.integer;
2184 if (serialised.size != instance->data_size)
2187 return memcmp (serialised.data,
2188 instance->data.string,
2189 instance->data_size) == 0;
2195 serialise_tree (TreeInstance *tree,
2196 GVariantSerialised *serialised)
2198 GVariantSerialised empty = { };
2200 *serialised = empty;
2201 tree_filler (serialised, tree);
2202 serialised->data = g_malloc (serialised->size);
2203 tree_filler (serialised, tree);
2207 test_byteswap (void)
2209 GVariantSerialised one, two;
2212 tree = tree_instance_new (NULL, 3);
2213 serialise_tree (tree, &one);
2215 i_am_writing_byteswapped = TRUE;
2216 serialise_tree (tree, &two);
2217 i_am_writing_byteswapped = FALSE;
2219 g_variant_serialised_byteswap (two);
2221 g_assert_cmpint (one.size, ==, two.size);
2222 g_assert (memcmp (one.data, two.data, one.size) == 0);
2224 tree_instance_free (tree);
2230 test_byteswaps (void)
2234 for (i = 0; i < 200; i++)
2237 g_variant_type_info_assert_no_infos ();
2241 test_fuzz (gdouble *fuzziness)
2243 GVariantSerialised serialised;
2246 /* make an instance */
2247 tree = tree_instance_new (NULL, 3);
2250 serialise_tree (tree, &serialised);
2252 g_assert (g_variant_serialised_is_normal (serialised));
2253 g_assert (check_tree (tree, serialised));
2255 if (serialised.size)
2257 gboolean fuzzed = FALSE;
2264 for (i = 0; i < serialised.size; i++)
2265 if (randomly (*fuzziness))
2267 serialised.data[i] += g_test_rand_int_range (1, 256);
2272 /* at least one byte in the serialised data has changed.
2274 * this means that at least one of the following is true:
2276 * - the serialised data now represents a different value:
2277 * check_tree() will return FALSE
2279 * - the serialised data is in non-normal form:
2280 * g_variant_serialiser_is_normal() will return FALSE
2282 * we always do both checks to increase exposure of the serialiser
2285 a = g_variant_serialised_is_normal (serialised);
2286 b = check_tree (tree, serialised);
2288 g_assert (!a || !b);
2291 tree_instance_free (tree);
2292 g_free (serialised.data);
2297 test_fuzzes (gpointer data)
2302 fuzziness = GPOINTER_TO_INT (data) / 100.;
2304 for (i = 0; i < 200; i++)
2305 test_fuzz (&fuzziness);
2307 g_variant_type_info_assert_no_infos ();
2311 tree_instance_get_gvariant (TreeInstance *tree)
2313 const GVariantType *type;
2316 type = (GVariantType *) g_variant_type_info_get_type_string (tree->info);
2318 switch (g_variant_type_info_get_type_char (tree->info))
2320 case G_VARIANT_TYPE_INFO_CHAR_MAYBE:
2322 const GVariantType *child_type;
2325 if (tree->n_children)
2326 child = tree_instance_get_gvariant (tree->children[0]);
2330 child_type = g_variant_type_element (type);
2332 if (child != NULL && randomly (0.5))
2335 result = g_variant_new_maybe (child_type, child);
2339 case G_VARIANT_TYPE_INFO_CHAR_ARRAY:
2341 const GVariantType *child_type;
2342 GVariant **children;
2345 children = g_new (GVariant *, tree->n_children);
2346 for (i = 0; i < tree->n_children; i++)
2347 children[i] = tree_instance_get_gvariant (tree->children[i]);
2349 child_type = g_variant_type_element (type);
2351 if (i > 0 && randomly (0.5))
2354 result = g_variant_new_array (child_type, children, tree->n_children);
2359 case G_VARIANT_TYPE_INFO_CHAR_TUPLE:
2361 GVariant **children;
2364 children = g_new (GVariant *, tree->n_children);
2365 for (i = 0; i < tree->n_children; i++)
2366 children[i] = tree_instance_get_gvariant (tree->children[i]);
2368 result = g_variant_new_tuple (children, tree->n_children);
2373 case G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY:
2375 GVariant *key, *val;
2377 g_assert (tree->n_children == 2);
2379 key = tree_instance_get_gvariant (tree->children[0]);
2380 val = tree_instance_get_gvariant (tree->children[1]);
2382 result = g_variant_new_dict_entry (key, val);
2386 case G_VARIANT_TYPE_INFO_CHAR_VARIANT:
2390 g_assert (tree->n_children == 1);
2392 value = tree_instance_get_gvariant (tree->children[0]);
2393 result = g_variant_new_variant (value);
2398 result = g_variant_new_boolean (tree->data.integer > 0);
2402 result = g_variant_new_byte (tree->data.integer);
2406 result = g_variant_new_int16 (tree->data.integer);
2410 result = g_variant_new_uint16 (tree->data.integer);
2414 result = g_variant_new_int32 (tree->data.integer);
2418 result = g_variant_new_uint32 (tree->data.integer);
2422 result = g_variant_new_int64 (tree->data.integer);
2426 result = g_variant_new_uint64 (tree->data.integer);
2430 result = g_variant_new_handle (tree->data.integer);
2434 result = g_variant_new_double (tree->data.floating);
2438 result = g_variant_new_string (tree->data.string);
2442 result = g_variant_new_object_path (tree->data.string);
2446 result = g_variant_new_signature (tree->data.string);
2450 g_assert_not_reached ();
2457 tree_instance_check_gvariant (TreeInstance *tree,
2460 const GVariantType *type;
2462 type = (GVariantType *) g_variant_type_info_get_type_string (tree->info);
2463 g_assert (g_variant_is_of_type (value, type));
2465 switch (g_variant_type_info_get_type_char (tree->info))
2467 case G_VARIANT_TYPE_INFO_CHAR_MAYBE:
2472 child = g_variant_get_maybe (value);
2474 if (child != NULL && tree->n_children == 1)
2475 equal = tree_instance_check_gvariant (tree->children[0], child);
2476 else if (child == NULL && tree->n_children == 0)
2482 g_variant_unref (child);
2488 case G_VARIANT_TYPE_INFO_CHAR_ARRAY:
2489 case G_VARIANT_TYPE_INFO_CHAR_TUPLE:
2490 case G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY:
2494 if (g_variant_n_children (value) != tree->n_children)
2497 for (i = 0; i < tree->n_children; i++)
2502 child = g_variant_get_child_value (value, i);
2503 equal = tree_instance_check_gvariant (tree->children[i], child);
2504 g_variant_unref (child);
2514 case G_VARIANT_TYPE_INFO_CHAR_VARIANT:
2516 const gchar *str1, *str2;
2520 child = g_variant_get_variant (value);
2521 str1 = g_variant_get_type_string (child);
2522 str2 = g_variant_type_info_get_type_string (tree->children[0]->info);
2523 /* GVariant only keeps one copy of type strings around */
2524 equal = str1 == str2 &&
2525 tree_instance_check_gvariant (tree->children[0], child);
2527 g_variant_unref (child);
2534 return g_variant_get_boolean (value) == tree->data.integer;
2537 return g_variant_get_byte (value) == (guchar) tree->data.integer;
2540 return g_variant_get_int16 (value) == (gint16) tree->data.integer;
2543 return g_variant_get_uint16 (value) == (guint16) tree->data.integer;
2546 return g_variant_get_int32 (value) == (gint32) tree->data.integer;
2549 return g_variant_get_uint32 (value) == (guint32) tree->data.integer;
2552 return g_variant_get_int64 (value) == (gint64) tree->data.integer;
2555 return g_variant_get_uint64 (value) == (guint64) tree->data.integer;
2558 return g_variant_get_handle (value) == (gint32) tree->data.integer;
2562 gdouble floating = g_variant_get_double (value);
2564 return memcmp (&floating, &tree->data.floating, sizeof floating) == 0;
2570 return strcmp (g_variant_get_string (value, NULL),
2571 tree->data.string) == 0;
2574 g_assert_not_reached ();
2579 tree_instance_build_gvariant (TreeInstance *tree,
2580 GVariantBuilder *builder,
2583 const GVariantType *type;
2585 type = (GVariantType *) g_variant_type_info_get_type_string (tree->info);
2587 if (g_variant_type_is_container (type))
2591 /* force GVariantBuilder to guess the type half the time */
2592 if (guess_ok && randomly (0.5))
2594 if (g_variant_type_is_array (type) && tree->n_children)
2595 type = G_VARIANT_TYPE_ARRAY;
2597 if (g_variant_type_is_maybe (type) && tree->n_children)
2598 type = G_VARIANT_TYPE_MAYBE;
2600 if (g_variant_type_is_tuple (type))
2601 type = G_VARIANT_TYPE_TUPLE;
2603 if (g_variant_type_is_dict_entry (type))
2604 type = G_VARIANT_TYPE_DICT_ENTRY;
2609 g_variant_builder_open (builder, type);
2611 for (i = 0; i < tree->n_children; i++)
2612 tree_instance_build_gvariant (tree->children[i], builder, guess_ok);
2614 g_variant_builder_close (builder);
2617 g_variant_builder_add_value (builder, tree_instance_get_gvariant (tree));
2622 tree_instance_check_iter (TreeInstance *tree,
2627 value = g_variant_iter_next_value (iter);
2629 if (g_variant_is_container (value))
2633 iter = g_variant_iter_new (value);
2634 g_variant_unref (value);
2636 if (g_variant_iter_n_children (iter) != tree->n_children)
2638 g_variant_iter_free (iter);
2642 for (i = 0; i < tree->n_children; i++)
2643 if (!tree_instance_check_iter (tree->children[i], iter))
2645 g_variant_iter_free (iter);
2649 g_assert (g_variant_iter_next_value (iter) == NULL);
2650 g_variant_iter_free (iter);
2659 equal = tree_instance_check_gvariant (tree, value);
2660 g_variant_unref (value);
2667 test_container (void)
2673 tree = tree_instance_new (NULL, 3);
2674 value = g_variant_ref_sink (tree_instance_get_gvariant (tree));
2676 s1 = g_variant_print (value, TRUE);
2677 g_assert (tree_instance_check_gvariant (tree, value));
2679 g_variant_get_data (value);
2681 s2 = g_variant_print (value, TRUE);
2682 g_assert (tree_instance_check_gvariant (tree, value));
2684 g_assert_cmpstr (s1, ==, s2);
2686 if (g_variant_is_container (value))
2688 GVariantBuilder builder;
2694 g_variant_builder_init (&builder, G_VARIANT_TYPE_VARIANT);
2695 tree_instance_build_gvariant (tree, &builder, TRUE);
2696 built = g_variant_builder_end (&builder);
2697 g_variant_ref_sink (built);
2698 g_variant_get_data (built);
2699 val = g_variant_get_variant (built);
2701 s3 = g_variant_print (val, TRUE);
2702 g_assert_cmpstr (s1, ==, s3);
2704 g_variant_iter_init (&iter, built);
2705 g_assert (tree_instance_check_iter (tree, &iter));
2706 g_assert (g_variant_iter_next_value (&iter) == NULL);
2708 g_variant_unref (built);
2709 g_variant_unref (val);
2713 tree_instance_free (tree);
2714 g_variant_unref (value);
2722 /* Test some different methods of creating strings */
2725 v = g_variant_new_string ("foo");
2726 g_assert_cmpstr (g_variant_get_string (v, NULL), ==, "foo");
2727 g_variant_unref (v);
2730 v = g_variant_new_take_string (g_strdup ("foo"));
2731 g_assert_cmpstr (g_variant_get_string (v, NULL), ==, "foo");
2732 g_variant_unref (v);
2734 v = g_variant_new_printf ("%s %d", "foo", 123);
2735 g_assert_cmpstr (g_variant_get_string (v, NULL), ==, "foo 123");
2736 g_variant_unref (v);
2742 const gchar invalid[] = "hello\xffworld";
2745 /* ensure that the test data is not valid utf8... */
2746 g_assert (!g_utf8_validate (invalid, -1, NULL));
2748 /* load the data untrusted */
2749 value = g_variant_new_from_data (G_VARIANT_TYPE_STRING,
2750 invalid, sizeof invalid,
2753 /* ensure that the problem is caught and we get valid UTF-8 */
2754 g_assert (g_utf8_validate (g_variant_get_string (value, NULL), -1, NULL));
2755 g_variant_unref (value);
2758 /* now load it trusted */
2759 value = g_variant_new_from_data (G_VARIANT_TYPE_STRING,
2760 invalid, sizeof invalid,
2763 /* ensure we get the invalid data (ie: make sure that time wasn't
2764 * wasted on validating data that was marked as trusted)
2766 g_assert (g_variant_get_string (value, NULL) == invalid);
2767 g_variant_unref (value);
2771 test_containers (void)
2775 for (i = 0; i < 100; i++)
2780 g_variant_type_info_assert_no_infos ();
2784 test_format_strings (void)
2789 g_assert (g_variant_format_string_scan ("i", NULL, &end) && *end == '\0');
2790 g_assert (g_variant_format_string_scan ("@i", NULL, &end) && *end == '\0');
2791 g_assert (g_variant_format_string_scan ("@ii", NULL, &end) && *end == 'i');
2792 g_assert (g_variant_format_string_scan ("^a&s", NULL, &end) && *end == '\0');
2793 g_assert (g_variant_format_string_scan ("(^as)", NULL, &end) &&
2795 g_assert (!g_variant_format_string_scan ("(^s)", NULL, &end));
2796 g_assert (!g_variant_format_string_scan ("(^a)", NULL, &end));
2797 g_assert (!g_variant_format_string_scan ("(z)", NULL, &end));
2798 g_assert (!g_variant_format_string_scan ("az", NULL, &end));
2799 g_assert (!g_variant_format_string_scan ("{**}", NULL, &end));
2800 g_assert (!g_variant_format_string_scan ("{@**}", NULL, &end));
2801 g_assert (g_variant_format_string_scan ("{@y*}", NULL, &end) &&
2803 g_assert (g_variant_format_string_scan ("{yv}", NULL, &end) &&
2805 g_assert (!g_variant_format_string_scan ("{&?v}", NULL, &end));
2806 g_assert (g_variant_format_string_scan ("{@?v}", NULL, &end) &&
2808 g_assert (!g_variant_format_string_scan ("{&@sv}", NULL, &end));
2809 g_assert (!g_variant_format_string_scan ("{@&sv}", NULL, &end));
2810 g_assert (g_variant_format_string_scan ("{&sv}", NULL, &end) &&
2812 g_assert (!g_variant_format_string_scan ("{vv}", NULL, &end));
2813 g_assert (!g_variant_format_string_scan ("{y}", NULL, &end));
2814 g_assert (!g_variant_format_string_scan ("{yyy}", NULL, &end));
2815 g_assert (!g_variant_format_string_scan ("{ya}", NULL, &end));
2816 g_assert (g_variant_format_string_scan ("&s", NULL, &end) && *end == '\0');
2817 g_assert (!g_variant_format_string_scan ("&as", NULL, &end));
2818 g_assert (!g_variant_format_string_scan ("@z", NULL, &end));
2819 g_assert (!g_variant_format_string_scan ("az", NULL, &end));
2820 g_assert (!g_variant_format_string_scan ("a&s", NULL, &end));
2822 type = g_variant_format_string_scan_type ("mm(@xy^a&s*?@?)", NULL, &end);
2823 g_assert (type && *end == '\0');
2824 g_assert (g_variant_type_equal (type, G_VARIANT_TYPE ("mm(xyas*?\?)")));
2825 g_variant_type_free (type);
2827 type = g_variant_format_string_scan_type ("mm(@xy^a&*?@?)", NULL, NULL);
2828 g_assert (type == NULL);
2832 do_failed_test (const char *test,
2833 const gchar *pattern)
2835 g_test_trap_subprocess (test, 1000000, 0);
2836 g_test_trap_assert_failed ();
2837 g_test_trap_assert_stderr (pattern);
2841 test_invalid_varargs (void)
2846 if (!g_test_undefined ())
2849 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
2850 "*GVariant format string*");
2851 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
2852 "*valid_format_string*");
2853 value = g_variant_new ("z");
2854 g_test_assert_expected_messages ();
2855 g_assert (value == NULL);
2857 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
2858 "*valid GVariant format string as a prefix*");
2859 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
2860 "*valid_format_string*");
2861 value = g_variant_new_va ("z", &end, NULL);
2862 g_test_assert_expected_messages ();
2863 g_assert (value == NULL);
2865 value = g_variant_new ("y", 'a');
2866 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
2867 "*type of 'q' but * has a type of 'y'*");
2868 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
2869 "*valid_format_string*");
2870 g_variant_get (value, "q");
2871 g_test_assert_expected_messages ();
2872 g_variant_unref (value);
2876 check_and_free (GVariant *value,
2879 gchar *valstr = g_variant_print (value, FALSE);
2880 g_assert_cmpstr (str, ==, valstr);
2881 g_variant_unref (value);
2886 test_varargs_empty_array (void)
2888 g_variant_new ("(a{s*})", NULL);
2890 g_assert_not_reached ();
2897 GVariantBuilder array;
2899 g_variant_builder_init (&array, G_VARIANT_TYPE_ARRAY);
2900 g_variant_builder_add_parsed (&array, "{'size', <(%i, %i)> }", 800, 600);
2901 g_variant_builder_add (&array, "{sv}", "title",
2902 g_variant_new_string ("Test case"));
2903 g_variant_builder_add_value (&array,
2904 g_variant_new_dict_entry (g_variant_new_string ("temperature"),
2905 g_variant_new_variant (
2906 g_variant_new_double (37.5))));
2907 check_and_free (g_variant_new ("(ma{sv}m(a{sv})ma{sv}ii)",
2908 NULL, FALSE, NULL, &array, 7777, 8888),
2909 "(nothing, nothing, {'size': <(800, 600)>, "
2910 "'title': <'Test case'>, "
2911 "'temperature': <37.5>}, "
2914 check_and_free (g_variant_new ("(imimimmimmimmi)",
2921 "(123, nothing, 123, nothing, just nothing, 123)");
2923 check_and_free (g_variant_new ("(ybnixd)",
2924 'a', 1, 22, 33, (guint64) 44, 5.5),
2925 "(0x61, true, 22, 33, 44, 5.5)");
2927 check_and_free (g_variant_new ("(@y?*rv)",
2928 g_variant_new ("y", 'a'),
2929 g_variant_new ("y", 'b'),
2930 g_variant_new ("y", 'c'),
2931 g_variant_new ("(y)", 'd'),
2932 g_variant_new ("y", 'e')),
2933 "(0x61, 0x62, 0x63, (0x64,), <byte 0x65>)");
2937 GVariantBuilder array;
2944 g_variant_builder_init (&array, G_VARIANT_TYPE_ARRAY);
2945 for (i = 0; i < 100; i++)
2947 number = g_strdup_printf ("%d", i);
2948 g_variant_builder_add (&array, "s", number);
2952 value = g_variant_builder_end (&array);
2953 g_variant_iter_init (&iter, value);
2956 while (g_variant_iter_loop (&iter, "s", &number))
2958 gchar *check = g_strdup_printf ("%d", i++);
2959 g_assert_cmpstr (number, ==, check);
2962 g_assert (number == NULL);
2963 g_assert (i == 100);
2965 g_variant_unref (value);
2967 g_variant_builder_init (&array, G_VARIANT_TYPE_ARRAY);
2968 for (i = 0; i < 100; i++)
2969 g_variant_builder_add (&array, "mi", i % 2 == 0, i);
2970 value = g_variant_builder_end (&array);
2973 g_variant_iter_init (&iter, value);
2974 while (g_variant_iter_loop (&iter, "mi", NULL, &val))
2975 g_assert (val == i++ || val == 0);
2976 g_assert (i == 100);
2979 g_variant_iter_init (&iter, value);
2980 while (g_variant_iter_loop (&iter, "mi", &just, &val))
2987 g_assert (val == this);
2992 g_assert (val == 0);
2995 g_assert (i == 100);
2997 g_variant_unref (value);
3001 const gchar *strvector[] = {"/hello", "/world", NULL};
3002 const gchar *test_strs[] = {"/foo", "/bar", "/baz" };
3003 GVariantBuilder builder;
3004 GVariantIter *array;
3012 g_variant_builder_init (&builder, G_VARIANT_TYPE ("as"));
3013 g_variant_builder_add (&builder, "s", "/foo");
3014 g_variant_builder_add (&builder, "s", "/bar");
3015 g_variant_builder_add (&builder, "s", "/baz");
3016 value = g_variant_new("(as^as^a&s)", &builder, strvector, strvector);
3017 g_variant_iter_init (&tuple, value);
3018 g_variant_iter_next (&tuple, "as", &array);
3021 while (g_variant_iter_loop (array, "s", &str))
3022 g_assert_cmpstr (str, ==, test_strs[i++]);
3025 g_variant_iter_free (array);
3028 g_variant_iter_init (&tuple, value);
3029 g_variant_iter_next (&tuple, "as", &array);
3032 while (g_variant_iter_loop (array, "&s", &str))
3033 g_assert_cmpstr (str, ==, test_strs[i++]);
3036 g_variant_iter_free (array);
3038 g_variant_iter_next (&tuple, "^a&s", &strv);
3039 g_variant_iter_next (&tuple, "^as", &my_strv);
3041 g_assert_cmpstr (strv[0], ==, "/hello");
3042 g_assert_cmpstr (strv[1], ==, "/world");
3043 g_assert (strv[2] == NULL);
3044 g_assert_cmpstr (my_strv[0], ==, "/hello");
3045 g_assert_cmpstr (my_strv[1], ==, "/world");
3046 g_assert (my_strv[2] == NULL);
3048 g_variant_unref (value);
3049 g_strfreev (my_strv);
3054 const gchar *strvector[] = {"/hello", "/world", NULL};
3055 const gchar *test_strs[] = {"/foo", "/bar", "/baz" };
3056 GVariantBuilder builder;
3057 GVariantIter *array;
3065 g_variant_builder_init (&builder, G_VARIANT_TYPE_OBJECT_PATH_ARRAY);
3066 g_variant_builder_add (&builder, "o", "/foo");
3067 g_variant_builder_add (&builder, "o", "/bar");
3068 g_variant_builder_add (&builder, "o", "/baz");
3069 value = g_variant_new("(ao^ao^a&o)", &builder, strvector, strvector);
3070 g_variant_iter_init (&tuple, value);
3071 g_variant_iter_next (&tuple, "ao", &array);
3074 while (g_variant_iter_loop (array, "o", &str))
3075 g_assert_cmpstr (str, ==, test_strs[i++]);
3078 g_variant_iter_free (array);
3081 g_variant_iter_init (&tuple, value);
3082 g_variant_iter_next (&tuple, "ao", &array);
3085 while (g_variant_iter_loop (array, "&o", &str))
3086 g_assert_cmpstr (str, ==, test_strs[i++]);
3089 g_variant_iter_free (array);
3091 g_variant_iter_next (&tuple, "^a&o", &strv);
3092 g_variant_iter_next (&tuple, "^ao", &my_strv);
3094 g_assert_cmpstr (strv[0], ==, "/hello");
3095 g_assert_cmpstr (strv[1], ==, "/world");
3096 g_assert (strv[2] == NULL);
3097 g_assert_cmpstr (my_strv[0], ==, "/hello");
3098 g_assert_cmpstr (my_strv[1], ==, "/world");
3099 g_assert (my_strv[2] == NULL);
3101 g_variant_unref (value);
3102 g_strfreev (my_strv);
3107 const gchar *strvector[] = { "i", "ii", "iii", "iv", "v", "vi", NULL };
3108 GVariantBuilder builder;
3117 g_variant_builder_init (&builder, G_VARIANT_TYPE ("aas"));
3118 g_variant_builder_open (&builder, G_VARIANT_TYPE ("as"));
3119 for (i = 0; i < 6; i++)
3121 g_variant_builder_add (&builder, "s", strvector[i]);
3123 g_variant_builder_add (&builder, "&s", strvector[i]);
3124 g_variant_builder_close (&builder);
3125 g_variant_builder_add (&builder, "^as", strvector);
3126 g_variant_builder_add (&builder, "^as", strvector);
3127 value = g_variant_new ("aas", &builder);
3129 g_variant_iter_init (&iter, value);
3130 while (g_variant_iter_loop (&iter, "^as", &strv))
3131 for (i = 0; i < 6; i++)
3132 g_assert_cmpstr (strv[i], ==, strvector[i]);
3134 g_variant_iter_init (&iter, value);
3135 while (g_variant_iter_loop (&iter, "^a&s", &strv))
3136 for (i = 0; i < 6; i++)
3137 g_assert_cmpstr (strv[i], ==, strvector[i]);
3139 g_variant_iter_init (&iter, value);
3140 while (g_variant_iter_loop (&iter, "as", &i2))
3145 while (g_variant_iter_loop (i2, "s", &str))
3146 g_assert_cmpstr (str, ==, strvector[i++]);
3150 g_variant_iter_init (&iter, value);
3151 i3 = g_variant_iter_copy (&iter);
3152 while (g_variant_iter_loop (&iter, "@as", &sub))
3154 gchar *str = g_variant_print (sub, TRUE);
3155 g_assert_cmpstr (str, ==,
3156 "['i', 'ii', 'iii', 'iv', 'v', 'vi']");
3160 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
3161 "*NULL has already been returned*");
3162 g_variant_iter_next_value (&iter);
3163 g_test_assert_expected_messages ();
3165 while (g_variant_iter_loop (i3, "*", &sub))
3167 gchar *str = g_variant_print (sub, TRUE);
3168 g_assert_cmpstr (str, ==,
3169 "['i', 'ii', 'iii', 'iv', 'v', 'vi']");
3173 g_variant_iter_free (i3);
3175 for (i = 0; i < g_variant_n_children (value); i++)
3179 g_variant_get_child (value, i, "*", &sub);
3181 for (j = 0; j < g_variant_n_children (sub); j++)
3183 const gchar *str = NULL;
3186 g_variant_get_child (sub, j, "&s", &str);
3187 g_assert_cmpstr (str, ==, strvector[j]);
3189 cval = g_variant_get_child_value (sub, j);
3190 g_variant_get (cval, "&s", &str);
3191 g_assert_cmpstr (str, ==, strvector[j]);
3192 g_variant_unref (cval);
3195 g_variant_unref (sub);
3198 g_variant_unref (value);
3217 /* test all 'nothing' */
3218 value = g_variant_new ("(mymbmnmqmimumxmtmhmdmv)",
3221 FALSE, (gint16) 123,
3222 FALSE, (guint16) 123,
3223 FALSE, (gint32) 123,
3224 FALSE, (guint32) 123,
3225 FALSE, (gint64) 123,
3226 FALSE, (guint64) 123,
3228 FALSE, (gdouble) 37.5,
3232 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3246 memset (justs, 1, sizeof justs);
3247 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3259 g_assert (!(justs[0] || justs[1] || justs[2] || justs[3] || justs[4] ||
3260 justs[5] || justs[6] || justs[7] || justs[8] || justs[9]));
3263 memset (justs, 1, sizeof justs);
3264 byteval = i16val = u16val = i32val = u32val = i64val = u64val = hval = 88;
3268 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3269 &justs[0], &byteval,
3280 g_assert (!(justs[0] || justs[1] || justs[2] || justs[3] || justs[4] ||
3281 justs[5] || justs[6] || justs[7] || justs[8] || justs[9]));
3282 g_assert (byteval == '\0' && bval == FALSE);
3283 g_assert (i16val == 0 && u16val == 0 && i32val == 0 &&
3284 u32val == 0 && i64val == 0 && u64val == 0 &&
3285 hval == 0 && dval == 0.0);
3286 g_assert (vval == NULL);
3289 byteval = i16val = u16val = i32val = u32val = i64val = u64val = hval = 88;
3293 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3305 g_assert (byteval == '\0' && bval == FALSE);
3306 g_assert (i16val == 0 && u16val == 0 && i32val == 0 &&
3307 u32val == 0 && i64val == 0 && u64val == 0 &&
3308 hval == 0 && dval == 0.0);
3309 g_assert (vval == NULL);
3311 g_variant_unref (value);
3314 /* test all 'just' */
3315 value = g_variant_new ("(mymbmnmqmimumxmtmhmdmv)",
3319 TRUE, (guint16) 123,
3321 TRUE, (guint32) 123,
3323 TRUE, (guint64) 123,
3325 TRUE, (gdouble) 37.5,
3326 g_variant_new ("()"));
3329 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3343 memset (justs, 0, sizeof justs);
3344 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3356 g_assert (justs[0] && justs[1] && justs[2] && justs[3] && justs[4] &&
3357 justs[5] && justs[6] && justs[7] && justs[8] && justs[9]);
3360 memset (justs, 0, sizeof justs);
3361 byteval = i16val = u16val = i32val = u32val = i64val = u64val = hval = 88;
3365 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3366 &justs[0], &byteval,
3377 g_assert (justs[0] && justs[1] && justs[2] && justs[3] && justs[4] &&
3378 justs[5] && justs[6] && justs[7] && justs[8] && justs[9]);
3379 g_assert (byteval == 'a' && bval == TRUE);
3380 g_assert (i16val == 123 && u16val == 123 && i32val == 123 &&
3381 u32val == 123 && i64val == 123 && u64val == 123 &&
3382 hval == -1 && dval == 37.5);
3383 g_assert (g_variant_is_of_type (vval, G_VARIANT_TYPE_UNIT));
3384 g_variant_unref (vval);
3387 byteval = i16val = u16val = i32val = u32val = i64val = u64val = hval = 88;
3391 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3403 g_assert (byteval == 'a' && bval == TRUE);
3404 g_assert (i16val == 123 && u16val == 123 && i32val == 123 &&
3405 u32val == 123 && i64val == 123 && u64val == 123 &&
3406 hval == -1 && dval == 37.5);
3407 g_assert (g_variant_is_of_type (vval, G_VARIANT_TYPE_UNIT));
3408 g_variant_unref (vval);
3410 g_variant_unref (value);
3417 value = g_variant_new ("(masas)", NULL, NULL);
3418 g_variant_ref_sink (value);
3420 str = g_variant_print (value, TRUE);
3421 g_assert_cmpstr (str, ==, "(@mas nothing, @as [])");
3422 g_variant_unref (value);
3425 do_failed_test ("/gvariant/varargs/subprocess/empty-array",
3426 "*which type of empty array*");
3429 g_variant_type_info_assert_no_infos ();
3433 hash_get (GVariant *value,
3434 const gchar *format,
3437 const gchar *endptr = NULL;
3441 hash = g_str_has_suffix (format, "#");
3443 va_start (ap, format);
3444 g_variant_get_va (value, format, hash ? &endptr : NULL, &ap);
3448 g_assert (*endptr == '#');
3452 hash_new (const gchar *format,
3455 const gchar *endptr = NULL;
3460 hash = g_str_has_suffix (format, "#");
3462 va_start (ap, format);
3463 value = g_variant_new_va (format, hash ? &endptr : NULL, &ap);
3467 g_assert (*endptr == '#');
3479 value = hash_new ("i", 234);
3480 hash_get (value, "i", &x);
3481 g_assert (x == 234);
3482 g_variant_unref (value);
3485 value = hash_new ("i#", 234);
3486 hash_get (value, "i#", &x);
3487 g_assert (x == 234);
3488 g_variant_unref (value);
3490 g_variant_type_info_assert_no_infos ();
3494 test_builder_memory (void)
3496 GVariantBuilder *hb;
3499 hb = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
3500 g_variant_builder_open (hb, G_VARIANT_TYPE_ARRAY);
3501 g_variant_builder_open (hb, G_VARIANT_TYPE_ARRAY);
3502 g_variant_builder_open (hb, G_VARIANT_TYPE_ARRAY);
3503 g_variant_builder_add (hb, "s", "some value");
3504 g_variant_builder_ref (hb);
3505 g_variant_builder_unref (hb);
3506 g_variant_builder_unref (hb);
3508 hb = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
3509 g_variant_builder_unref (hb);
3511 hb = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
3512 g_variant_builder_clear (hb);
3513 g_variant_builder_unref (hb);
3515 g_variant_builder_init (&sb, G_VARIANT_TYPE_ARRAY);
3516 g_variant_builder_open (&sb, G_VARIANT_TYPE_ARRAY);
3517 g_variant_builder_open (&sb, G_VARIANT_TYPE_ARRAY);
3518 g_variant_builder_add (&sb, "s", "some value");
3519 g_variant_builder_clear (&sb);
3521 g_variant_type_info_assert_no_infos ();
3527 GVariant *items[4096];
3531 table = g_hash_table_new_full (g_variant_hash, g_variant_equal,
3532 (GDestroyNotify ) g_variant_unref,
3535 for (i = 0; i < G_N_ELEMENTS (items); i++)
3541 tree = tree_instance_new (NULL, 0);
3542 items[i] = tree_instance_get_gvariant (tree);
3543 tree_instance_free (tree);
3545 for (j = 0; j < i; j++)
3546 if (g_variant_equal (items[i], items[j]))
3548 g_variant_unref (items[i]);
3552 g_hash_table_insert (table,
3553 g_variant_ref_sink (items[i]),
3554 GINT_TO_POINTER (i));
3557 for (i = 0; i < G_N_ELEMENTS (items); i++)
3561 result = g_hash_table_lookup (table, items[i]);
3562 g_assert_cmpint (GPOINTER_TO_INT (result), ==, i);
3565 g_hash_table_unref (table);
3567 g_variant_type_info_assert_no_infos ();
3571 test_gv_byteswap (void)
3573 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
3574 # define native16(x) x, 0
3575 # define swapped16(x) 0, x
3577 # define native16(x) 0, x
3578 # define swapped16(x) x, 0
3580 /* all kinds of of crazy randomised testing already performed on the
3581 * byteswapper in the /gvariant/serialiser/byteswap test and all kinds
3582 * of crazy randomised testing performed against the serialiser
3583 * normalisation functions in the /gvariant/serialiser/fuzz/ tests.
3585 * just test a few simple cases here to make sure they each work
3587 guchar validbytes[] = { 'a', '\0', swapped16(66), 2,
3589 'b', '\0', swapped16(77), 2,
3591 guchar corruptbytes[] = { 'a', '\0', swapped16(66), 2,
3593 'b', '\0', swapped16(77), 2,
3595 guint valid_data[4], corrupt_data[4];
3596 GVariant *value, *swapped;
3597 gchar *string, *string2;
3599 memcpy (valid_data, validbytes, sizeof validbytes);
3600 memcpy (corrupt_data, corruptbytes, sizeof corruptbytes);
3603 value = g_variant_new_from_data (G_VARIANT_TYPE ("a(sn)"),
3604 valid_data, sizeof validbytes, TRUE,
3606 swapped = g_variant_byteswap (value);
3607 g_variant_unref (value);
3608 g_assert (g_variant_get_size (swapped) == 13);
3609 string = g_variant_print (swapped, FALSE);
3610 g_variant_unref (swapped);
3611 g_assert_cmpstr (string, ==, "[('a', 66), ('b', 77)]");
3614 /* untrusted but valid */
3615 value = g_variant_new_from_data (G_VARIANT_TYPE ("a(sn)"),
3616 valid_data, sizeof validbytes, FALSE,
3618 swapped = g_variant_byteswap (value);
3619 g_variant_unref (value);
3620 g_assert (g_variant_get_size (swapped) == 13);
3621 string = g_variant_print (swapped, FALSE);
3622 g_variant_unref (swapped);
3623 g_assert_cmpstr (string, ==, "[('a', 66), ('b', 77)]");
3626 /* untrusted, invalid */
3627 value = g_variant_new_from_data (G_VARIANT_TYPE ("a(sn)"),
3628 corrupt_data, sizeof corruptbytes, FALSE,
3630 string = g_variant_print (value, FALSE);
3631 swapped = g_variant_byteswap (value);
3632 g_variant_unref (value);
3633 g_assert (g_variant_get_size (swapped) == 13);
3634 value = g_variant_byteswap (swapped);
3635 g_variant_unref (swapped);
3636 string2 = g_variant_print (value, FALSE);
3637 g_assert (g_variant_get_size (value) == 13);
3638 g_variant_unref (value);
3639 g_assert_cmpstr (string, ==, string2);
3653 tree = tree_instance_new (NULL, 3);
3654 value = tree_instance_get_gvariant (tree);
3655 tree_instance_free (tree);
3657 pt = g_variant_print (value, TRUE);
3658 p = g_variant_print (value, FALSE);
3660 parsed = g_variant_parse (NULL, pt, NULL, NULL, NULL);
3661 res = g_variant_print (parsed, FALSE);
3662 g_assert_cmpstr (p, ==, res);
3663 g_variant_unref (parsed);
3666 parsed = g_variant_parse (g_variant_get_type (value), p,
3668 res = g_variant_print (parsed, TRUE);
3669 g_assert_cmpstr (pt, ==, res);
3670 g_variant_unref (parsed);
3673 g_variant_unref (value);
3683 for (i = 0; i < 100; i++)
3690 GError *error = NULL;
3695 for (i = 0; i < 127; i++)
3699 val = g_variant_new_string (str);
3700 p = g_variant_print (val, FALSE);
3701 g_variant_unref (val);
3703 val = g_variant_parse (NULL, p, NULL, NULL, &error);
3704 p2 = g_variant_print (val, FALSE);
3706 g_assert_cmpstr (str, ==, g_variant_get_string (val, NULL));
3707 g_assert_cmpstr (p, ==, p2);
3709 g_variant_unref (val);
3714 /* another mini test */
3719 value = g_variant_parse (G_VARIANT_TYPE_INT32, "1 2 3", NULL, &end, NULL);
3720 g_assert_cmpint (g_variant_get_int32 (value), ==, 1);
3721 /* make sure endptr returning works */
3722 g_assert_cmpstr (end, ==, " 2 3");
3723 g_variant_unref (value);
3726 /* unicode mini test */
3729 const gchar orig[] = "a\xc5\x82\xf0\x9d\x84\x9e \t\n";
3733 value = g_variant_new_string (orig);
3734 printed = g_variant_print (value, FALSE);
3735 g_variant_unref (value);
3737 g_assert_cmpstr (printed, ==, "'a\xc5\x82\xf0\x9d\x84\x9e \\t\\n'");
3738 value = g_variant_parse (NULL, printed, NULL, NULL, NULL);
3739 g_assert_cmpstr (g_variant_get_string (value, NULL), ==, orig);
3740 g_variant_unref (value);
3744 /* inf/nan mini test */
3746 const gchar *tests[] = { "inf", "-inf", "nan" };
3749 gchar *printed_down;
3752 for (i = 0; i < G_N_ELEMENTS (tests); i++)
3754 GError *error = NULL;
3755 value = g_variant_parse (NULL, tests[i], NULL, NULL, &error);
3756 printed = g_variant_print (value, FALSE);
3757 /* Canonicalize to lowercase; https://bugzilla.gnome.org/show_bug.cgi?id=704585 */
3758 printed_down = g_ascii_strdown (printed, -1);
3759 g_assert (g_str_has_prefix (printed_down, tests[i]));
3761 g_free (printed_down);
3762 g_variant_unref (value);
3766 g_variant_type_info_assert_no_infos ();
3770 test_parse_failures (void)
3772 const gchar *test[] = {
3773 "[1, 2,", "6:", "expected value",
3774 "", "0:", "expected value",
3775 "(1, 2,", "6:", "expected value",
3776 "<1", "2:", "expected '>'",
3777 "[]", "0-2:", "unable to infer",
3778 "(,", "1:", "expected value",
3779 "[4,'']", "1-2,3-5:", "common type",
3780 "[4, '', 5]", "1-2,4-6:", "common type",
3781 "['', 4, 5]", "1-3,5-6:", "common type",
3782 "[4, 5, '']", "1-2,7-9:", "common type",
3783 "[[4], [], ['']]", "1-4,10-14:", "common type",
3784 "[[], [4], ['']]", "5-8,10-14:", "common type",
3785 "just", "4:", "expected value",
3786 "nothing", "0-7:", "unable to infer",
3787 "just [4, '']", "6-7,9-11:", "common type",
3788 "[[4,'']]", "2-3,4-6:", "common type",
3789 "([4,''],)", "2-3,4-6:", "common type",
3791 "{}", "0-2:", "unable to infer",
3792 "{[1,2],[3,4]}", "0-13:", "basic types",
3793 "{[1,2]:[3,4]}", "0-13:", "basic types",
3794 "justt", "0-5:", "unknown keyword",
3795 "nothng", "0-6:", "unknown keyword",
3796 "uint33", "0-6:", "unknown keyword",
3797 "@mi just ''", "9-11:", "can not parse as",
3798 "@ai ['']", "5-7:", "can not parse as",
3799 "@(i) ('',)", "6-8:", "can not parse as",
3800 "[[], 5]", "1-3,5-6:", "common type",
3801 "[[5], 5]", "1-4,6-7:", "common type",
3802 "5 5", "2:", "expected end of input",
3803 "[5, [5, '']]", "5-6,8-10:", "common type",
3804 "@i just 5", "3-9:", "can not parse as",
3805 "@i nothing", "3-10:", "can not parse as",
3806 "@i []", "3-5:", "can not parse as",
3807 "@i ()", "3-5:", "can not parse as",
3808 "@ai (4,)", "4-8:", "can not parse as",
3809 "@(i) []", "5-7:", "can not parse as",
3810 "(5 5)", "3:", "expected ','",
3811 "[5 5]", "3:", "expected ',' or ']'",
3812 "(5, 5 5)", "6:", "expected ',' or ')'",
3813 "[5, 5 5]", "6:", "expected ',' or ']'",
3814 "<@i []>", "4-6:", "can not parse as",
3815 "<[5 5]>", "4:", "expected ',' or ']'",
3816 "{[4,''],5}", "2-3,4-6:", "common type",
3817 "{5,[4,'']}", "4-5,6-8:", "common type",
3818 "@i {1,2}", "3-8:", "can not parse as",
3819 "{@i '', 5}", "4-6:", "can not parse as",
3820 "{5, @i ''}", "7-9:", "can not parse as",
3821 "@ai {}", "4-6:", "can not parse as",
3822 "{@i '': 5}", "4-6:", "can not parse as",
3823 "{5: @i ''}", "7-9:", "can not parse as",
3824 "{<4,5}", "3:", "expected '>'",
3825 "{4,<5}", "5:", "expected '>'",
3826 "{4,5,6}", "4:", "expected '}'",
3827 "{5 5}", "3:", "expected ':' or ','",
3828 "{4: 5: 6}", "5:", "expected ',' or '}'",
3829 "{4:5,<6:7}", "7:", "expected '>'",
3830 "{4:5,6:<7}", "9:", "expected '>'",
3831 "{4:5,6 7}", "7:", "expected ':'",
3832 "@o 'foo'", "3-8:", "object path",
3833 "@g 'zzz'", "3-8:", "signature",
3834 "@i true", "3-7:", "can not parse as",
3835 "@z 4", "0-2:", "invalid type",
3836 "@a* []", "0-3:", "definite",
3837 "@ai [3 3]", "7:", "expected ',' or ']'",
3838 "18446744073709551616", "0-20:", "too big for any type",
3839 "-18446744073709551616", "0-21:", "too big for any type",
3840 "byte 256", "5-8:", "out of range for type",
3841 "byte -1", "5-7:", "out of range for type",
3842 "int16 32768", "6-11:", "out of range for type",
3843 "int16 -32769", "6-12:", "out of range for type",
3844 "uint16 -1", "7-9:", "out of range for type",
3845 "uint16 65536", "7-12:", "out of range for type",
3846 "2147483648", "0-10:", "out of range for type",
3847 "-2147483649", "0-11:", "out of range for type",
3848 "uint32 -1", "7-9:", "out of range for type",
3849 "uint32 4294967296", "7-17:", "out of range for type",
3850 "@x 9223372036854775808", "3-22:", "out of range for type",
3851 "@x -9223372036854775809", "3-23:", "out of range for type",
3852 "@t -1", "3-5:", "out of range for type",
3853 "@t 18446744073709551616", "3-23:", "too big for any type",
3854 "handle 2147483648", "7-17:", "out of range for type",
3855 "handle -2147483649", "7-18:", "out of range for type",
3856 "1.798e308", "0-9:", "too big for any type",
3857 "37.5a488", "4-5:", "invalid character",
3858 "0x7ffgf", "5-6:", "invalid character",
3859 "07758", "4-5:", "invalid character",
3860 "123a5", "3-4:", "invalid character",
3861 "@ai 123", "4-7:", "can not parse as",
3862 "'\"\\'", "0-4:", "unterminated string",
3863 "'\"\\'\\", "0-5:", "unterminated string",
3864 "boolean 4", "8-9:", "can not parse as",
3865 "int32 true", "6-10:", "can not parse as",
3866 "[double 5, int32 5]", "1-9,11-18:", "common type",
3867 "string 4", "7-8:", "can not parse as"
3871 for (i = 0; i < G_N_ELEMENTS (test); i += 3)
3873 GError *error = NULL;
3876 value = g_variant_parse (NULL, test[i], NULL, NULL, &error);
3877 g_assert (value == NULL);
3879 if (!strstr (error->message, test[i+2]))
3880 g_error ("test %d: Can't find '%s' in '%s'", i / 3,
3881 test[i+2], error->message);
3883 if (!g_str_has_prefix (error->message, test[i+1]))
3884 g_error ("test %d: Expected location '%s' in '%s'", i / 3,
3885 test[i+1], error->message);
3887 g_error_free (error);
3892 test_parse_bad_format_char (void)
3894 g_variant_new_parsed ("%z");
3896 g_assert_not_reached ();
3900 test_parse_bad_format_string (void)
3902 g_variant_new_parsed ("uint32 %i", 2);
3904 g_assert_not_reached ();
3908 test_parse_bad_args (void)
3910 g_variant_new_parsed ("%@i", g_variant_new_uint32 (2));
3912 g_assert_not_reached ();
3916 test_parse_positional (void)
3919 check_and_free (g_variant_new_parsed ("[('one', 1), (%s, 2),"
3920 " ('three', %i)]", "two", 3),
3921 "[('one', 1), ('two', 2), ('three', 3)]");
3922 value = g_variant_new_parsed ("[('one', 1), (%s, 2),"
3923 " ('three', %u)]", "two", 3);
3924 g_assert (g_variant_is_of_type (value, G_VARIANT_TYPE ("a(su)")));
3925 check_and_free (value, "[('one', 1), ('two', 2), ('three', 3)]");
3926 check_and_free (g_variant_new_parsed ("{%s:%i}", "one", 1), "{'one': 1}");
3928 if (g_test_undefined ())
3930 do_failed_test ("/gvariant/parse/subprocess/bad-format-char",
3931 "*GVariant format string*");
3933 do_failed_test ("/gvariant/parse/subprocess/bad-format-string",
3934 "*can not parse as*");
3936 do_failed_test ("/gvariant/parse/subprocess/bad-args",
3937 "*expected GVariant of type 'i'*");
3942 test_floating (void)
3946 value = g_variant_new_int32 (42);
3947 g_assert (g_variant_is_floating (value));
3948 g_variant_ref_sink (value);
3949 g_assert (!g_variant_is_floating (value));
3950 g_variant_unref (value);
3954 test_bytestring (void)
3956 const gchar *test_string = "foo,bar,baz,quux,\xffoooo";
3960 const gchar *const_str;
3961 GVariant *untrusted_empty;
3963 strv = g_strsplit (test_string, ",", 0);
3965 value = g_variant_new_bytestring_array ((const gchar **) strv, -1);
3966 g_assert (g_variant_is_floating (value));
3969 str = g_variant_print (value, FALSE);
3970 g_variant_unref (value);
3972 value = g_variant_parse (NULL, str, NULL, NULL, NULL);
3975 strv = g_variant_dup_bytestring_array (value, NULL);
3976 g_variant_unref (value);
3978 str = g_strjoinv (",", strv);
3981 g_assert_cmpstr (str, ==, test_string);
3984 strv = g_strsplit (test_string, ",", 0);
3985 value = g_variant_new ("(^aay^a&ay^ay^&ay)",
3986 strv, strv, strv[0], strv[0]);
3989 g_variant_get_child (value, 0, "^a&ay", &strv);
3990 str = g_strjoinv (",", strv);
3992 g_assert_cmpstr (str, ==, test_string);
3995 g_variant_get_child (value, 0, "^aay", &strv);
3996 str = g_strjoinv (",", strv);
3998 g_assert_cmpstr (str, ==, test_string);
4001 g_variant_get_child (value, 1, "^a&ay", &strv);
4002 str = g_strjoinv (",", strv);
4004 g_assert_cmpstr (str, ==, test_string);
4007 g_variant_get_child (value, 1, "^aay", &strv);
4008 str = g_strjoinv (",", strv);
4010 g_assert_cmpstr (str, ==, test_string);
4013 g_variant_get_child (value, 2, "^ay", &str);
4014 g_assert_cmpstr (str, ==, "foo");
4017 g_variant_get_child (value, 2, "^&ay", &str);
4018 g_assert_cmpstr (str, ==, "foo");
4020 g_variant_get_child (value, 3, "^ay", &str);
4021 g_assert_cmpstr (str, ==, "foo");
4024 g_variant_get_child (value, 3, "^&ay", &str);
4025 g_assert_cmpstr (str, ==, "foo");
4026 g_variant_unref (value);
4028 untrusted_empty = g_variant_new_from_data (G_VARIANT_TYPE ("ay"), NULL, 0, FALSE, NULL, NULL);
4029 value = g_variant_get_normal_form (untrusted_empty);
4030 const_str = g_variant_get_bytestring (value);
4032 g_variant_unref (value);
4033 g_variant_unref (untrusted_empty);
4037 test_lookup_value (void)
4040 const gchar *dict, *key, *value;
4042 { "@a{ss} {'x': 'y'}", "x", "'y'" },
4043 { "@a{ss} {'x': 'y'}", "y" },
4044 { "@a{os} {'/x': 'y'}", "/x", "'y'" },
4045 { "@a{os} {'/x': 'y'}", "/y" },
4046 { "@a{sv} {'x': <'y'>}", "x", "'y'" },
4047 { "@a{sv} {'x': <5>}", "x", "5" },
4048 { "@a{sv} {'x': <'y'>}", "y" }
4052 for (i = 0; i < G_N_ELEMENTS (cases); i++)
4054 GVariant *dictionary;
4058 dictionary = g_variant_parse (NULL, cases[i].dict, NULL, NULL, NULL);
4059 value = g_variant_lookup_value (dictionary, cases[i].key, NULL);
4060 g_variant_unref (dictionary);
4062 if (value == NULL && cases[i].value == NULL)
4065 g_assert (value && cases[i].value);
4066 p = g_variant_print (value, FALSE);
4067 g_assert_cmpstr (cases[i].value, ==, p);
4068 g_variant_unref (value);
4081 dict = g_variant_parse (NULL,
4082 "{'a': <5>, 'b': <'c'>}",
4085 ok = g_variant_lookup (dict, "a", "i", &num);
4087 g_assert_cmpint (num, ==, 5);
4089 ok = g_variant_lookup (dict, "a", "&s", &str);
4092 ok = g_variant_lookup (dict, "q", "&s", &str);
4095 ok = g_variant_lookup (dict, "b", "i", &num);
4098 ok = g_variant_lookup (dict, "b", "&s", &str);
4100 g_assert_cmpstr (str, ==, "c");
4102 ok = g_variant_lookup (dict, "q", "&s", &str);
4105 g_variant_unref (dict);
4114 a = g_variant_new_byte (5);
4115 b = g_variant_new_byte (6);
4116 g_assert (g_variant_compare (a, b) < 0);
4117 g_variant_unref (a);
4118 g_variant_unref (b);
4119 a = g_variant_new_string ("abc");
4120 b = g_variant_new_string ("abd");
4121 g_assert (g_variant_compare (a, b) < 0);
4122 g_variant_unref (a);
4123 g_variant_unref (b);
4124 a = g_variant_new_boolean (FALSE);
4125 b = g_variant_new_boolean (TRUE);
4126 g_assert (g_variant_compare (a, b) < 0);
4127 g_variant_unref (a);
4128 g_variant_unref (b);
4132 test_fixed_array (void)
4141 a = g_variant_new_parsed ("[1,2,3,4,5]");
4142 elts = g_variant_get_fixed_array (a, &n_elts, sizeof (gint32));
4143 g_assert (n_elts == 5);
4144 for (i = 0; i < 5; i++)
4145 g_assert_cmpint (elts[i], ==, i + 1);
4146 g_variant_unref (a);
4149 for (i = 0; i < 5; i++)
4151 a = g_variant_new_fixed_array (G_VARIANT_TYPE_INT32, values,
4152 G_N_ELEMENTS (values), sizeof (values[0]));
4153 g_assert_cmpstr (g_variant_get_type_string (a), ==, "ai");
4154 elts = g_variant_get_fixed_array (a, &n_elts, sizeof (gint32));
4155 g_assert (n_elts == 5);
4156 for (i = 0; i < 5; i++)
4157 g_assert_cmpint (elts[i], ==, i + 1);
4158 g_variant_unref (a);
4162 test_check_format_string (void)
4166 value = g_variant_new ("(sas)", "foo", NULL);
4167 g_variant_ref_sink (value);
4169 g_assert (g_variant_check_format_string (value, "(s*)", TRUE));
4170 g_assert (g_variant_check_format_string (value, "(s*)", FALSE));
4171 g_assert (!g_variant_check_format_string (value, "(u*)", TRUE));
4172 g_assert (!g_variant_check_format_string (value, "(u*)", FALSE));
4174 g_assert (g_variant_check_format_string (value, "(&s*)", FALSE));
4175 g_test_expect_message ("GLib", G_LOG_LEVEL_CRITICAL, "*contains a '&' character*");
4176 g_assert (!g_variant_check_format_string (value, "(&s*)", TRUE));
4177 g_test_assert_expected_messages ();
4179 g_assert (g_variant_check_format_string (value, "(s^as)", TRUE));
4180 g_assert (g_variant_check_format_string (value, "(s^as)", FALSE));
4182 g_test_expect_message ("GLib", G_LOG_LEVEL_CRITICAL, "*contains a '&' character*");
4183 g_assert (!g_variant_check_format_string (value, "(s^a&s)", TRUE));
4184 g_test_assert_expected_messages ();
4185 g_assert (g_variant_check_format_string (value, "(s^a&s)", FALSE));
4187 g_variant_unref (value);
4189 /* Do it again with a type that will let us put a '&' after a '^' */
4190 value = g_variant_new ("(say)", "foo", NULL);
4191 g_variant_ref_sink (value);
4193 g_assert (g_variant_check_format_string (value, "(s*)", TRUE));
4194 g_assert (g_variant_check_format_string (value, "(s*)", FALSE));
4195 g_assert (!g_variant_check_format_string (value, "(u*)", TRUE));
4196 g_assert (!g_variant_check_format_string (value, "(u*)", FALSE));
4198 g_assert (g_variant_check_format_string (value, "(&s*)", FALSE));
4199 g_test_expect_message ("GLib", G_LOG_LEVEL_CRITICAL, "*contains a '&' character*");
4200 g_assert (!g_variant_check_format_string (value, "(&s*)", TRUE));
4201 g_test_assert_expected_messages ();
4203 g_assert (g_variant_check_format_string (value, "(s^ay)", TRUE));
4204 g_assert (g_variant_check_format_string (value, "(s^ay)", FALSE));
4206 g_test_expect_message ("GLib", G_LOG_LEVEL_CRITICAL, "*contains a '&' character*");
4207 g_assert (!g_variant_check_format_string (value, "(s^&ay)", TRUE));
4208 g_test_assert_expected_messages ();
4209 g_assert (g_variant_check_format_string (value, "(s^&ay)", FALSE));
4211 g_variant_unref (value);
4215 verify_gvariant_checksum (const gchar *sha256,
4220 checksum = g_compute_checksum_for_data (G_CHECKSUM_SHA256,
4221 g_variant_get_data (v),
4222 g_variant_get_size (v));
4223 g_assert_cmpstr (sha256, ==, checksum);
4228 verify_gvariant_checksum_va (const gchar *sha256,
4235 va_start (args, fmt);
4237 v = g_variant_new_va (fmt, NULL, &args);
4238 g_variant_ref_sink (v);
4239 #if G_BYTE_ORDER == G_BIG_ENDIAN
4241 GVariant *byteswapped = g_variant_byteswap (v);
4242 g_variant_unref (v);
4249 verify_gvariant_checksum (sha256, v);
4251 g_variant_unref (v);
4255 test_checksum_basic (void)
4257 verify_gvariant_checksum_va ("e8a4b2ee7ede79a3afb332b5b6cc3d952a65fd8cffb897f5d18016577c33d7cc",
4259 verify_gvariant_checksum_va ("c53e363c33b00cfce298229ee83856b8a98c2e6126cab13f65899f62473b0df5",
4261 verify_gvariant_checksum_va ("2b4c342f5433ebe591a1da77e013d1b72475562d48578dca8b84bac6651c3cb9",
4263 verify_gvariant_checksum_va ("12a3ae445661ce5dee78d0650d33362dec29c4f82af05e7e57fb595bbbacf0ca",
4265 verify_gvariant_checksum_va ("e25a59b24440eb6c833aa79c93b9840e6eab6966add0dacf31df7e9e7000f5b3",
4267 verify_gvariant_checksum_va ("4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a",
4269 verify_gvariant_checksum_va ("ca2fd00fa001190744c15c317643ab092e7048ce086a243e2be9437c898de1bb",
4274 test_checksum_nested (void)
4276 static const char* const strv[] = {"foo", "bar", "baz", NULL};
4278 verify_gvariant_checksum_va ("31fbc92f08fddaca716188fe4b5d44ae122fc6306fd3c6925af53cfa47ea596d",
4280 verify_gvariant_checksum_va ("01759d683cead856d1d386d59af0578841698a424a265345ad5413122f220de8",
4281 "(su)", "moocow", 79);
4282 verify_gvariant_checksum_va ("52b3ae95f19b3e642ea1d01185aea14a09004c1d1712672644427403a8a0afe6",
4283 "(qyst)", G_MAXUINT16, 9, "moocow", G_MAXUINT64);
4284 verify_gvariant_checksum_va ("6fc6f4524161c3ae0d316812d7088e3fcd372023edaea2d7821093be40ae1060",
4285 "(@ay)", g_variant_new_bytestring ("\xFF\xFF\xFF"));
4286 verify_gvariant_checksum_va ("572aca386e1a983dd23bb6eb6e3dfa72eef9ca7c7744581aa800e18d7d9d0b0b",
4288 verify_gvariant_checksum_va ("4bddf6174c791bb44fc6a4106573031690064df34b741033a0122ed8dc05bcf3",
4289 "(yvu)", 254, g_variant_new ("(^as)", strv), 42);
4299 const guint8 values[5] = { 1, 2, 3, 4, 5 };
4304 bytes = g_bytes_new (&values, 5);
4305 a = g_variant_new_from_bytes (G_VARIANT_TYPE_BYTESTRING, bytes, TRUE);
4306 g_bytes_unref (bytes);
4308 elts = g_variant_get_fixed_array (a, &n_elts, sizeof (guint8));
4309 g_assert (n_elts == 5);
4310 for (i = 0; i < 5; i++)
4311 g_assert_cmpint (elts[i], ==, i + 1);
4313 bytes2 = g_variant_get_data_as_bytes (a);
4314 g_variant_unref (a);
4316 bytes = g_bytes_new (&values, 5);
4317 g_assert (g_bytes_equal (bytes, bytes2));
4318 g_bytes_unref (bytes);
4319 g_bytes_unref (bytes2);
4321 tuple = g_variant_new_parsed ("['foo', 'bar']");
4322 bytes = g_variant_get_data_as_bytes (tuple); /* force serialisation */
4323 a = g_variant_get_child_value (tuple, 1);
4324 bytes2 = g_variant_get_data_as_bytes (a);
4325 g_assert (!g_bytes_equal (bytes, bytes2));
4327 g_bytes_unref (bytes);
4328 g_bytes_unref (bytes2);
4329 g_variant_unref (a);
4330 g_variant_unref (tuple);
4334 main (int argc, char **argv)
4338 g_test_init (&argc, &argv, NULL);
4340 g_test_add_func ("/gvariant/type", test_gvarianttype);
4341 g_test_add_func ("/gvariant/typeinfo", test_gvarianttypeinfo);
4342 g_test_add_func ("/gvariant/serialiser/maybe", test_maybes);
4343 g_test_add_func ("/gvariant/serialiser/array", test_arrays);
4344 g_test_add_func ("/gvariant/serialiser/tuple", test_tuples);
4345 g_test_add_func ("/gvariant/serialiser/variant", test_variants);
4346 g_test_add_func ("/gvariant/serialiser/strings", test_strings);
4347 g_test_add_func ("/gvariant/serialiser/byteswap", test_byteswaps);
4349 for (i = 1; i <= 20; i += 4)
4353 testname = g_strdup_printf ("/gvariant/serialiser/fuzz/%d%%", i);
4354 g_test_add_data_func (testname, GINT_TO_POINTER (i),
4355 (gpointer) test_fuzzes);
4359 g_test_add_func ("/gvariant/string", test_string);
4360 g_test_add_func ("/gvariant/utf8", test_utf8);
4361 g_test_add_func ("/gvariant/containers", test_containers);
4362 g_test_add_func ("/gvariant/format-strings", test_format_strings);
4363 g_test_add_func ("/gvariant/invalid-varargs", test_invalid_varargs);
4364 g_test_add_func ("/gvariant/varargs", test_varargs);
4365 g_test_add_func ("/gvariant/varargs/subprocess/empty-array", test_varargs_empty_array);
4366 g_test_add_func ("/gvariant/valist", test_valist);
4367 g_test_add_func ("/gvariant/builder-memory", test_builder_memory);
4368 g_test_add_func ("/gvariant/hashing", test_hashing);
4369 g_test_add_func ("/gvariant/byteswap", test_gv_byteswap);
4370 g_test_add_func ("/gvariant/parser", test_parses);
4371 g_test_add_func ("/gvariant/parse-failures", test_parse_failures);
4372 g_test_add_func ("/gvariant/parse-positional", test_parse_positional);
4373 g_test_add_func ("/gvariant/parse/subprocess/bad-format-char", test_parse_bad_format_char);
4374 g_test_add_func ("/gvariant/parse/subprocess/bad-format-string", test_parse_bad_format_string);
4375 g_test_add_func ("/gvariant/parse/subprocess/bad-args", test_parse_bad_args);
4376 g_test_add_func ("/gvariant/floating", test_floating);
4377 g_test_add_func ("/gvariant/bytestring", test_bytestring);
4378 g_test_add_func ("/gvariant/lookup-value", test_lookup_value);
4379 g_test_add_func ("/gvariant/lookup", test_lookup);
4380 g_test_add_func ("/gvariant/compare", test_compare);
4381 g_test_add_func ("/gvariant/fixed-array", test_fixed_array);
4382 g_test_add_func ("/gvariant/check-format-string", test_check_format_string);
4384 g_test_add_func ("/gvariant/checksum-basic", test_checksum_basic);
4385 g_test_add_func ("/gvariant/checksum-nested", test_checksum_nested);
4387 g_test_add_func ("/gvariant/gbytes", test_gbytes);
4389 return g_test_run ();