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_is_subtype_of (ctype, type));
616 g_assert (g_variant_type_is_subtype_of (type, ctype));
618 /* check if the type is indefinite */
619 if (!g_variant_type_is_definite (type))
621 struct typestack ts = { type, NULL };
623 /* if it is indefinite, then replace one of the indefinite
624 * characters with a matching type and ensure that the result
625 * is a subtype of the original type. repeat.
627 subtype_check (type_string->str, &ts);
630 /* ensure that no indefinite characters appear */
631 g_assert (strcspn (type_string->str, "r?*") == type_string->len);
634 /* describe the type.
636 * exercises the type iterator interface
638 desc = describe_type (type);
640 /* make sure the description matches */
641 g_assert_cmpstr (desc, ==, description->str);
644 /* make an invalid mutation to the type and make sure the type
645 * validation routines catch it */
646 invalid = invalid_mutation (type_string->str);
647 g_assert (g_variant_type_string_is_valid (type_string->str));
648 g_assert (!g_variant_type_string_is_valid (invalid));
651 /* concatenate another type to the type string and ensure that
652 * the result is recognised as being invalid
654 other_type = append_type_string (type_string, description, FALSE, 2);
656 g_string_free (description, TRUE);
657 g_string_free (type_string, TRUE);
658 g_variant_type_free (other_type);
659 g_variant_type_free (type);
663 #define ALIGNED(x, y) (((x + (y - 1)) / y) * y)
665 /* do our own calculation of the fixed_size and alignment of a type
666 * using a simple algorithm to make sure the "fancy" one in the
667 * implementation is correct.
670 calculate_type_info (const GVariantType *type,
674 if (g_variant_type_is_array (type) ||
675 g_variant_type_is_maybe (type))
677 calculate_type_info (g_variant_type_element (type), NULL, alignment);
682 else if (g_variant_type_is_tuple (type) ||
683 g_variant_type_is_dict_entry (type))
685 if (g_variant_type_n_items (type))
687 const GVariantType *sub;
696 sub = g_variant_type_first (type);
702 calculate_type_info (sub, &this_fs, &this_al);
704 al = MAX (al, this_al);
714 size = ALIGNED (size, this_al);
718 while ((sub = g_variant_type_next (sub)));
720 size = ALIGNED (size, al);
741 if (g_variant_type_equal (type, G_VARIANT_TYPE_BOOLEAN) ||
742 g_variant_type_equal (type, G_VARIANT_TYPE_BYTE))
747 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT16) ||
748 g_variant_type_equal (type, G_VARIANT_TYPE_UINT16))
753 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32) ||
754 g_variant_type_equal (type, G_VARIANT_TYPE_UINT32) ||
755 g_variant_type_equal (type, G_VARIANT_TYPE_HANDLE))
760 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT64) ||
761 g_variant_type_equal (type, G_VARIANT_TYPE_UINT64) ||
762 g_variant_type_equal (type, G_VARIANT_TYPE_DOUBLE))
766 else if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING) ||
767 g_variant_type_equal (type, G_VARIANT_TYPE_OBJECT_PATH) ||
768 g_variant_type_equal (type, G_VARIANT_TYPE_SIGNATURE))
773 else if (g_variant_type_equal (type, G_VARIANT_TYPE_VARIANT))
779 g_assert_not_reached ();
789 /* same as the describe_type() function above, but iterates over
790 * typeinfo instead of types.
793 describe_info (GVariantTypeInfo *info)
797 switch (g_variant_type_info_get_type_char (info))
799 case G_VARIANT_TYPE_INFO_CHAR_MAYBE:
803 element = describe_info (g_variant_type_info_element (info));
804 result = g_strdup_printf ("m of %s", element);
809 case G_VARIANT_TYPE_INFO_CHAR_ARRAY:
813 element = describe_info (g_variant_type_info_element (info));
814 result = g_strdup_printf ("a of %s", element);
819 case G_VARIANT_TYPE_INFO_CHAR_TUPLE:
821 const gchar *sep = "";
826 string = g_string_new ("t of [");
827 length = g_variant_type_info_n_members (info);
829 for (i = 0; i < length; i++)
831 const GVariantMemberInfo *minfo;
834 g_string_append (string, sep);
837 minfo = g_variant_type_info_member_info (info, i);
838 subtype = describe_info (minfo->type_info);
839 g_string_append (string, subtype);
843 g_string_append_c (string, ']');
845 result = g_string_free (string, FALSE);
849 case G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY:
851 const GVariantMemberInfo *keyinfo, *valueinfo;
854 g_assert_cmpint (g_variant_type_info_n_members (info), ==, 2);
855 keyinfo = g_variant_type_info_member_info (info, 0);
856 valueinfo = g_variant_type_info_member_info (info, 1);
857 key = describe_info (keyinfo->type_info);
858 value = describe_info (valueinfo->type_info);
859 result = g_strjoin ("", "e of [", key, ", ", value, "]", NULL);
865 case G_VARIANT_TYPE_INFO_CHAR_VARIANT:
866 result = g_strdup ("V");
870 result = g_strdup (g_variant_type_info_get_type_string (info));
871 g_assert_cmpint (strlen (result), ==, 1);
878 /* check that the O(1) method of calculating offsets meshes with the
879 * results of simple iteration.
882 check_offsets (GVariantTypeInfo *info,
883 const GVariantType *type)
888 length = g_variant_type_info_n_members (info);
889 g_assert_cmpint (length, ==, g_variant_type_n_items (type));
891 /* the 'flavour' is the low order bits of the ending point of
892 * variable-size items in the tuple. this lets us test that the type
893 * info is correct for various starting alignments.
895 for (flavour = 0; flavour < 8; flavour++)
897 const GVariantType *subtype;
898 gsize last_offset_index;
903 subtype = g_variant_type_first (type);
904 last_offset_index = -1;
908 /* go through the tuple, keeping track of our position */
909 for (i = 0; i < length; i++)
914 calculate_type_info (subtype, &fixed_size, &alignment);
916 position = ALIGNED (position, alignment);
918 /* compare our current aligned position (ie: the start of this
919 * item) to the start offset that would be calculated if we
923 const GVariantMemberInfo *member;
926 member = g_variant_type_info_member_info (info, i);
927 g_assert_cmpint (member->i, ==, last_offset_index);
929 /* do the calculation using the typeinfo */
935 /* did we reach the same spot? */
936 g_assert_cmpint (start, ==, position);
941 /* fixed size. add that size. */
942 position += fixed_size;
946 /* variable size. do the flavouring. */
947 while ((position & 0x7) != flavour)
950 /* and store the offset, just like it would be in the
953 last_offset = position;
958 subtype = g_variant_type_next (subtype);
961 /* make sure we used up exactly all the types */
962 g_assert (subtype == NULL);
967 test_gvarianttypeinfo (void)
971 for (i = 0; i < 2000; i++)
973 GString *type_string, *description;
974 gsize fixed_size1, fixed_size2;
975 guint alignment1, alignment2;
976 GVariantTypeInfo *info;
980 type_string = g_string_new (NULL);
981 description = g_string_new (NULL);
984 type = append_type_string (type_string, description, TRUE, 6);
986 /* create a typeinfo for it */
987 info = g_variant_type_info_get (type);
989 /* make sure the typeinfo has the right type string */
990 g_assert_cmpstr (g_variant_type_info_get_type_string (info), ==,
993 /* calculate the alignment and fixed size, compare to the
994 * typeinfo's calculations
996 calculate_type_info (type, &fixed_size1, &alignment1);
997 g_variant_type_info_query (info, &alignment2, &fixed_size2);
998 g_assert_cmpint (fixed_size1, ==, fixed_size2);
999 g_assert_cmpint (alignment1, ==, alignment2 + 1);
1001 /* test the iteration functions over typeinfo structures by
1002 * "describing" the typeinfo and verifying equality.
1004 desc = describe_info (info);
1005 g_assert_cmpstr (desc, ==, description->str);
1007 /* do extra checks for containers */
1008 if (g_variant_type_is_array (type) ||
1009 g_variant_type_is_maybe (type))
1011 const GVariantType *element;
1015 element = g_variant_type_element (type);
1016 calculate_type_info (element, &efs1, &ea1);
1017 g_variant_type_info_query_element (info, &ea2, &efs2);
1018 g_assert_cmpint (efs1, ==, efs2);
1019 g_assert_cmpint (ea1, ==, ea2 + 1);
1021 g_assert_cmpint (ea1, ==, alignment1);
1022 g_assert_cmpint (0, ==, fixed_size1);
1024 else if (g_variant_type_is_tuple (type) ||
1025 g_variant_type_is_dict_entry (type))
1027 /* make sure the "magic constants" are working */
1028 check_offsets (info, type);
1031 g_string_free (type_string, TRUE);
1032 g_string_free (description, TRUE);
1033 g_variant_type_info_unref (info);
1034 g_variant_type_free (type);
1038 g_variant_type_info_assert_no_infos ();
1041 #define MAX_FIXED_MULTIPLIER 256
1042 #define MAX_INSTANCE_SIZE 1024
1043 #define MAX_ARRAY_CHILDREN 128
1044 #define MAX_TUPLE_CHILDREN 128
1046 /* this function generates a random type such that all characteristics
1047 * that are "interesting" to the serialiser are tested.
1049 * this basically means:
1050 * - test different alignments
1051 * - test variable sized items and fixed sized items
1052 * - test different fixed sizes
1055 random_type_string (void)
1057 const guchar base_types[] = "ynix";
1060 base_type = base_types[g_test_rand_int_range (0, 4)];
1062 if (g_test_rand_bit ())
1063 /* construct a fixed-sized type */
1065 char type_string[MAX_FIXED_MULTIPLIER];
1069 multiplier = g_test_rand_int_range (1, sizeof type_string - 1);
1071 type_string[i++] = '(';
1072 while (multiplier--)
1073 type_string[i++] = base_type;
1074 type_string[i++] = ')';
1076 return g_strndup (type_string, i);
1079 /* construct a variable-sized type */
1081 char type_string[2] = { 'a', base_type };
1083 return g_strndup (type_string, 2);
1089 GVariantTypeInfo *type_info;
1092 gboolean is_fixed_sized;
1096 #define INSTANCE_MAGIC 1287582829
1100 static RandomInstance *
1101 random_instance (GVariantTypeInfo *type_info)
1103 RandomInstance *instance;
1105 instance = g_slice_new (RandomInstance);
1107 if (type_info == NULL)
1109 gchar *str = random_type_string ();
1110 instance->type_info = g_variant_type_info_get (G_VARIANT_TYPE (str));
1114 instance->type_info = g_variant_type_info_ref (type_info);
1116 instance->seed = g_test_rand_int ();
1118 g_variant_type_info_query (instance->type_info,
1119 &instance->alignment,
1122 instance->is_fixed_sized = instance->size != 0;
1124 if (!instance->is_fixed_sized)
1125 instance->size = g_test_rand_int_range (0, MAX_INSTANCE_SIZE);
1127 instance->magic = INSTANCE_MAGIC;
1133 random_instance_free (RandomInstance *instance)
1135 g_variant_type_info_unref (instance->type_info);
1136 g_slice_free (RandomInstance, instance);
1140 append_instance_size (RandomInstance *instance,
1143 *offset += (-*offset) & instance->alignment;
1144 *offset += instance->size;
1148 random_instance_write (RandomInstance *instance,
1154 g_assert_cmpint ((gsize) buffer & ALIGN_BITS & instance->alignment, ==, 0);
1156 rand = g_rand_new_with_seed (instance->seed);
1157 for (i = 0; i < instance->size; i++)
1158 buffer[i] = g_rand_int (rand);
1163 append_instance_data (RandomInstance *instance,
1166 while (((gsize) *buffer) & instance->alignment)
1167 *(*buffer)++ = '\0';
1169 random_instance_write (instance, *buffer);
1170 *buffer += instance->size;
1174 random_instance_assert (RandomInstance *instance,
1181 g_assert_cmpint ((gsize) buffer & ALIGN_BITS & instance->alignment, ==, 0);
1182 g_assert_cmpint (size, ==, instance->size);
1184 rand = g_rand_new_with_seed (instance->seed);
1185 for (i = 0; i < instance->size; i++)
1187 guchar byte = g_rand_int (rand);
1189 g_assert (buffer[i] == byte);
1193 return i == instance->size;
1197 random_instance_check (RandomInstance *instance,
1204 g_assert_cmpint ((gsize) buffer & ALIGN_BITS & instance->alignment, ==, 0);
1206 if (size != instance->size)
1209 rand = g_rand_new_with_seed (instance->seed);
1210 for (i = 0; i < instance->size; i++)
1211 if (buffer[i] != (guchar) g_rand_int (rand))
1215 return i == instance->size;
1219 random_instance_filler (GVariantSerialised *serialised,
1222 RandomInstance *instance = data;
1224 g_assert (instance->magic == INSTANCE_MAGIC);
1226 if (serialised->type_info == NULL)
1227 serialised->type_info = instance->type_info;
1229 if (serialised->size == 0)
1230 serialised->size = instance->size;
1232 g_assert (serialised->type_info == instance->type_info);
1233 g_assert (serialised->size == instance->size);
1235 if (serialised->data)
1236 random_instance_write (instance, serialised->data);
1240 calculate_offset_size (gsize body_size,
1246 if (body_size + n_offsets <= G_MAXUINT8)
1249 if (body_size + 2 * n_offsets <= G_MAXUINT16)
1252 if (body_size + 4 * n_offsets <= G_MAXUINT32)
1255 /* the test case won't generate anything bigger */
1256 g_assert_not_reached ();
1260 flavoured_malloc (gsize size, gsize flavour)
1262 g_assert (flavour < 8);
1267 return ((gchar *) g_malloc (size + flavour)) + flavour;
1271 flavoured_free (gpointer data,
1276 g_free (((gchar *) data) - flavour);
1280 align_malloc (gsize size)
1284 #ifdef HAVE_POSIX_MEMALIGN
1285 if (posix_memalign (&mem, 8, size))
1286 g_error ("posix_memalign failed");
1288 /* NOTE: there may be platforms that lack posix_memalign() and also
1289 * have malloc() that returns non-8-aligned. if so, we need to try
1292 mem = malloc (size);
1299 align_free (gpointer mem)
1305 append_offset (guchar **offset_ptr,
1311 guchar bytes[sizeof (gsize)];
1315 tmpvalue.integer = GSIZE_TO_LE (offset);
1316 memcpy (*offset_ptr, tmpvalue.bytes, offset_size);
1317 *offset_ptr += offset_size;
1321 prepend_offset (guchar **offset_ptr,
1327 guchar bytes[sizeof (gsize)];
1331 *offset_ptr -= offset_size;
1332 tmpvalue.integer = GSIZE_TO_LE (offset);
1333 memcpy (*offset_ptr, tmpvalue.bytes, offset_size);
1339 GVariantTypeInfo *type_info;
1340 RandomInstance *instance;
1344 instance = random_instance (NULL);
1347 const gchar *element;
1350 element = g_variant_type_info_get_type_string (instance->type_info);
1351 tmp = g_strdup_printf ("m%s", element);
1352 type_info = g_variant_type_info_get (G_VARIANT_TYPE (tmp));
1356 needed_size = g_variant_serialiser_needed_size (type_info,
1357 random_instance_filler,
1359 g_assert_cmpint (needed_size, ==, 0);
1361 needed_size = g_variant_serialiser_needed_size (type_info,
1362 random_instance_filler,
1363 (gpointer *) &instance, 1);
1365 if (instance->is_fixed_sized)
1366 g_assert_cmpint (needed_size, ==, instance->size);
1368 g_assert_cmpint (needed_size, ==, instance->size + 1);
1373 ptr = data = align_malloc (needed_size);
1374 append_instance_data (instance, &ptr);
1376 if (!instance->is_fixed_sized)
1379 g_assert_cmpint (ptr - data, ==, needed_size);
1386 alignment = (instance->alignment & ALIGN_BITS) + 1;
1388 for (flavour = 0; flavour < 8; flavour += alignment)
1390 GVariantSerialised serialised;
1391 GVariantSerialised child;
1393 serialised.type_info = type_info;
1394 serialised.data = flavoured_malloc (needed_size, flavour);
1395 serialised.size = needed_size;
1397 g_variant_serialiser_serialise (serialised,
1398 random_instance_filler,
1399 (gpointer *) &instance, 1);
1400 child = g_variant_serialised_get_child (serialised, 0);
1401 g_assert (child.type_info == instance->type_info);
1402 random_instance_assert (instance, child.data, child.size);
1403 g_variant_type_info_unref (child.type_info);
1404 flavoured_free (serialised.data, flavour);
1408 g_variant_type_info_unref (type_info);
1409 random_instance_free (instance);
1418 for (i = 0; i < 1000; i++)
1421 g_variant_type_info_assert_no_infos ();
1427 GVariantTypeInfo *element_info;
1428 GVariantTypeInfo *array_info;
1429 RandomInstance **instances;
1436 gchar *element_type, *array_type;
1438 element_type = random_type_string ();
1439 array_type = g_strdup_printf ("a%s", element_type);
1441 element_info = g_variant_type_info_get (G_VARIANT_TYPE (element_type));
1442 array_info = g_variant_type_info_get (G_VARIANT_TYPE (array_type));
1443 g_assert (g_variant_type_info_element (array_info) == element_info);
1445 g_free (element_type);
1446 g_free (array_type);
1452 n_children = g_test_rand_int_range (0, MAX_ARRAY_CHILDREN);
1453 instances = g_new (RandomInstance *, n_children);
1454 for (i = 0; i < n_children; i++)
1455 instances[i] = random_instance (element_info);
1458 needed_size = g_variant_serialiser_needed_size (array_info,
1459 random_instance_filler,
1460 (gpointer *) instances,
1464 gsize element_fixed_size;
1465 gsize body_size = 0;
1468 for (i = 0; i < n_children; i++)
1469 append_instance_size (instances[i], &body_size);
1471 g_variant_type_info_query (element_info, NULL, &element_fixed_size);
1473 if (!element_fixed_size)
1475 offset_size = calculate_offset_size (body_size, n_children);
1477 if (offset_size == 0)
1483 g_assert_cmpint (needed_size, ==, body_size + n_children * offset_size);
1487 guchar *offset_ptr, *body_ptr;
1490 body_ptr = data = align_malloc (needed_size);
1491 offset_ptr = body_ptr + needed_size - offset_size * n_children;
1493 for (i = 0; i < n_children; i++)
1495 append_instance_data (instances[i], &body_ptr);
1496 append_offset (&offset_ptr, body_ptr - data, offset_size);
1499 g_assert (body_ptr == data + needed_size - offset_size * n_children);
1500 g_assert (offset_ptr == data + needed_size);
1508 g_variant_type_info_query (array_info, &alignment, NULL);
1509 alignment = (alignment & ALIGN_BITS) + 1;
1511 for (flavour = 0; flavour < 8; flavour += alignment)
1513 GVariantSerialised serialised;
1515 serialised.type_info = array_info;
1516 serialised.data = flavoured_malloc (needed_size, flavour);
1517 serialised.size = needed_size;
1519 g_variant_serialiser_serialise (serialised, random_instance_filler,
1520 (gpointer *) instances, n_children);
1522 g_assert (memcmp (serialised.data, data, serialised.size) == 0);
1523 g_assert (g_variant_serialised_n_children (serialised) == n_children);
1525 for (i = 0; i < n_children; i++)
1527 GVariantSerialised child;
1529 child = g_variant_serialised_get_child (serialised, i);
1530 g_assert (child.type_info == instances[i]->type_info);
1531 random_instance_assert (instances[i], child.data, child.size);
1532 g_variant_type_info_unref (child.type_info);
1535 flavoured_free (serialised.data, flavour);
1542 for (i = 0; i < n_children; i++)
1543 random_instance_free (instances[i]);
1547 g_variant_type_info_unref (element_info);
1548 g_variant_type_info_unref (array_info);
1557 for (i = 0; i < 100; i++)
1560 g_variant_type_info_assert_no_infos ();
1566 GVariantTypeInfo *type_info;
1567 RandomInstance **instances;
1568 gboolean fixed_size;
1575 n_children = g_test_rand_int_range (0, MAX_TUPLE_CHILDREN);
1576 instances = g_new (RandomInstance *, n_children);
1579 GString *type_string;
1585 type_string = g_string_new ("(");
1586 for (i = 0; i < n_children; i++)
1590 instances[i] = random_instance (NULL);
1592 alignment |= instances[i]->alignment;
1593 if (!instances[i]->is_fixed_sized)
1596 str = g_variant_type_info_get_type_string (instances[i]->type_info);
1597 g_string_append (type_string, str);
1599 g_string_append_c (type_string, ')');
1601 type_info = g_variant_type_info_get (G_VARIANT_TYPE (type_string->str));
1602 g_string_free (type_string, TRUE);
1605 needed_size = g_variant_serialiser_needed_size (type_info,
1606 random_instance_filler,
1607 (gpointer *) instances,
1610 gsize body_size = 0;
1614 for (i = 0; i < n_children; i++)
1616 append_instance_size (instances[i], &body_size);
1618 if (i != n_children - 1 && !instances[i]->is_fixed_sized)
1624 body_size += (-body_size) & alignment;
1626 g_assert ((body_size == 0) == (n_children == 0));
1627 if (n_children == 0)
1631 offset_size = calculate_offset_size (body_size, offsets);
1632 g_assert_cmpint (needed_size, ==, body_size + offsets * offset_size);
1640 body_ptr = data = align_malloc (needed_size);
1641 ofs_ptr = body_ptr + needed_size;
1643 for (i = 0; i < n_children; i++)
1645 append_instance_data (instances[i], &body_ptr);
1647 if (i != n_children - 1 && !instances[i]->is_fixed_sized)
1648 prepend_offset (&ofs_ptr, body_ptr - data, offset_size);
1653 while (((gsize) body_ptr) & alignment)
1656 g_assert ((body_ptr == data) == (n_children == 0));
1657 if (n_children == 0)
1663 g_assert (body_ptr == ofs_ptr);
1670 alignment = (alignment & ALIGN_BITS) + 1;
1672 for (flavour = 0; flavour < 8; flavour += alignment)
1674 GVariantSerialised serialised;
1676 serialised.type_info = type_info;
1677 serialised.data = flavoured_malloc (needed_size, flavour);
1678 serialised.size = needed_size;
1680 g_variant_serialiser_serialise (serialised, random_instance_filler,
1681 (gpointer *) instances, n_children);
1683 g_assert (memcmp (serialised.data, data, serialised.size) == 0);
1684 g_assert (g_variant_serialised_n_children (serialised) == n_children);
1686 for (i = 0; i < n_children; i++)
1688 GVariantSerialised child;
1690 child = g_variant_serialised_get_child (serialised, i);
1691 g_assert (child.type_info == instances[i]->type_info);
1692 random_instance_assert (instances[i], child.data, child.size);
1693 g_variant_type_info_unref (child.type_info);
1696 flavoured_free (serialised.data, flavour);
1703 for (i = 0; i < n_children; i++)
1704 random_instance_free (instances[i]);
1708 g_variant_type_info_unref (type_info);
1717 for (i = 0; i < 100; i++)
1720 g_variant_type_info_assert_no_infos ();
1726 GVariantTypeInfo *type_info;
1727 RandomInstance *instance;
1728 const gchar *type_string;
1733 type_info = g_variant_type_info_get (G_VARIANT_TYPE_VARIANT);
1734 instance = random_instance (NULL);
1736 type_string = g_variant_type_info_get_type_string (instance->type_info);
1737 len = strlen (type_string);
1739 needed_size = g_variant_serialiser_needed_size (type_info,
1740 random_instance_filler,
1741 (gpointer *) &instance, 1);
1743 g_assert_cmpint (needed_size, ==, instance->size + 1 + len);
1748 ptr = data = align_malloc (needed_size);
1749 append_instance_data (instance, &ptr);
1751 memcpy (ptr, type_string, len);
1754 g_assert (data + needed_size == ptr);
1761 /* variants are always 8-aligned */
1762 alignment = ALIGN_BITS + 1;
1764 for (flavour = 0; flavour < 8; flavour += alignment)
1766 GVariantSerialised serialised;
1767 GVariantSerialised child;
1769 serialised.type_info = type_info;
1770 serialised.data = flavoured_malloc (needed_size, flavour);
1771 serialised.size = needed_size;
1773 g_variant_serialiser_serialise (serialised, random_instance_filler,
1774 (gpointer *) &instance, 1);
1776 g_assert (memcmp (serialised.data, data, serialised.size) == 0);
1777 g_assert (g_variant_serialised_n_children (serialised) == 1);
1779 child = g_variant_serialised_get_child (serialised, 0);
1780 g_assert (child.type_info == instance->type_info);
1781 random_instance_check (instance, child.data, child.size);
1783 g_variant_type_info_unref (child.type_info);
1784 flavoured_free (serialised.data, flavour);
1788 g_variant_type_info_unref (type_info);
1789 random_instance_free (instance);
1794 test_variants (void)
1798 for (i = 0; i < 100; i++)
1801 g_variant_type_info_assert_no_infos ();
1814 #define is_objpath is_string | 2
1815 #define is_sig is_string | 4
1817 { is_nval, 0, NULL },
1818 { is_nval, 13, "hello\xffworld!" },
1819 { is_string, 13, "hello world!" },
1820 { is_nval, 13, "hello world\0" },
1821 { is_nval, 13, "hello\0world!" },
1822 { is_nval, 12, "hello world!" },
1824 { is_objpath, 2, "/" },
1825 { is_objpath, 3, "/a" },
1826 { is_string, 3, "//" },
1827 { is_objpath, 11, "/some/path" },
1828 { is_string, 12, "/some/path/" },
1829 { is_nval, 11, "/some\0path" },
1830 { is_string, 11, "/some\\path" },
1831 { is_string, 12, "/some//path" },
1832 { is_string, 12, "/some-/path" },
1836 { is_sig, 5, "(si)" },
1837 { is_string, 4, "(si" },
1838 { is_string, 2, "*" },
1839 { is_sig, 3, "ai" },
1840 { is_string, 3, "mi" },
1841 { is_string, 2, "r" },
1842 { is_sig, 15, "(yyy{sv}ssiai)" },
1843 { is_string, 16, "(yyy{yv}ssiai))" },
1844 { is_string, 15, "(yyy{vv}ssiai)" },
1845 { is_string, 15, "(yyy{sv)ssiai}" }
1849 for (i = 0; i < G_N_ELEMENTS (test_cases); i++)
1853 flags = g_variant_serialiser_is_string (test_cases[i].data,
1857 flags |= g_variant_serialiser_is_object_path (test_cases[i].data,
1861 flags |= g_variant_serialiser_is_signature (test_cases[i].data,
1865 g_assert (flags == test_cases[i].flags);
1869 typedef struct _TreeInstance TreeInstance;
1870 struct _TreeInstance
1872 GVariantTypeInfo *info;
1874 TreeInstance **children;
1885 static GVariantType *
1886 make_random_definite_type (int depth)
1888 GString *description;
1889 GString *type_string;
1892 description = g_string_new (NULL);
1893 type_string = g_string_new (NULL);
1894 type = append_type_string (type_string, description, TRUE, depth);
1895 g_string_free (description, TRUE);
1896 g_string_free (type_string, TRUE);
1902 make_random_string (gchar *string,
1904 const GVariantType *type)
1908 /* create strings that are valid signature strings */
1909 #define good_chars "bynqiuxthdsog"
1911 for (i = 0; i < size - 1; i++)
1912 string[i] = good_chars[g_test_rand_int_range (0, strlen (good_chars))];
1915 /* in case we need an object path, prefix a '/' */
1916 if (*g_variant_type_peek_string (type) == 'o')
1922 static TreeInstance *
1923 tree_instance_new (const GVariantType *type,
1926 const GVariantType *child_type = NULL;
1927 GVariantType *mytype = NULL;
1928 TreeInstance *instance;
1929 gboolean is_tuple_type;
1932 type = mytype = make_random_definite_type (depth);
1934 instance = g_slice_new (TreeInstance);
1935 instance->info = g_variant_type_info_get (type);
1936 instance->children = NULL;
1937 instance->n_children = 0;
1938 instance->data_size = 0;
1940 is_tuple_type = FALSE;
1942 switch (*g_variant_type_peek_string (type))
1944 case G_VARIANT_TYPE_INFO_CHAR_MAYBE:
1945 instance->n_children = g_test_rand_int_range (0, 2);
1946 child_type = g_variant_type_element (type);
1949 case G_VARIANT_TYPE_INFO_CHAR_ARRAY:
1950 instance->n_children = g_test_rand_int_range (0, MAX_ARRAY_CHILDREN);
1951 child_type = g_variant_type_element (type);
1954 case G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY:
1955 case G_VARIANT_TYPE_INFO_CHAR_TUPLE:
1956 instance->n_children = g_variant_type_n_items (type);
1957 child_type = g_variant_type_first (type);
1958 is_tuple_type = TRUE;
1961 case G_VARIANT_TYPE_INFO_CHAR_VARIANT:
1962 instance->n_children = 1;
1967 instance->data.integer = g_test_rand_int_range (0, 2);
1968 instance->data_size = 1;
1972 instance->data.integer = g_test_rand_int ();
1973 instance->data_size = 1;
1977 instance->data.integer = g_test_rand_int ();
1978 instance->data_size = 2;
1981 case 'i': case 'u': case 'h':
1982 instance->data.integer = g_test_rand_int ();
1983 instance->data_size = 4;
1987 instance->data.integer = g_test_rand_int ();
1988 instance->data.integer <<= 32;
1989 instance->data.integer |= (guint32) g_test_rand_int ();
1990 instance->data_size = 8;
1994 instance->data.floating = g_test_rand_double ();
1995 instance->data_size = 8;
1998 case 's': case 'o': case 'g':
1999 instance->data_size = g_test_rand_int_range (10, 20);
2000 make_random_string (instance->data.string, instance->data_size, type);
2004 if (instance->data_size == 0)
2005 /* no data -> it is a container */
2009 instance->children = g_new (TreeInstance *, instance->n_children);
2011 for (i = 0; i < instance->n_children; i++)
2013 instance->children[i] = tree_instance_new (child_type, depth - 1);
2016 child_type = g_variant_type_next (child_type);
2019 g_assert (!is_tuple_type || child_type == NULL);
2022 g_variant_type_free (mytype);
2028 tree_instance_free (TreeInstance *instance)
2032 g_variant_type_info_unref (instance->info);
2033 for (i = 0; i < instance->n_children; i++)
2034 tree_instance_free (instance->children[i]);
2035 g_free (instance->children);
2036 g_slice_free (TreeInstance, instance);
2039 static gboolean i_am_writing_byteswapped;
2042 tree_filler (GVariantSerialised *serialised,
2045 TreeInstance *instance = data;
2047 if (serialised->type_info == NULL)
2048 serialised->type_info = instance->info;
2050 if (instance->data_size == 0)
2051 /* is a container */
2053 if (serialised->size == 0)
2055 g_variant_serialiser_needed_size (instance->info, tree_filler,
2056 (gpointer *) instance->children,
2057 instance->n_children);
2059 if (serialised->data)
2060 g_variant_serialiser_serialise (*serialised, tree_filler,
2061 (gpointer *) instance->children,
2062 instance->n_children);
2067 if (serialised->size == 0)
2068 serialised->size = instance->data_size;
2070 if (serialised->data)
2072 switch (instance->data_size)
2075 *serialised->data = instance->data.integer;
2080 guint16 value = instance->data.integer;
2082 if (i_am_writing_byteswapped)
2083 value = GUINT16_SWAP_LE_BE (value);
2085 *(guint16 *) serialised->data = value;
2091 guint32 value = instance->data.integer;
2093 if (i_am_writing_byteswapped)
2094 value = GUINT32_SWAP_LE_BE (value);
2096 *(guint32 *) serialised->data = value;
2102 guint64 value = instance->data.integer;
2104 if (i_am_writing_byteswapped)
2105 value = GUINT64_SWAP_LE_BE (value);
2107 *(guint64 *) serialised->data = value;
2112 memcpy (serialised->data,
2113 instance->data.string,
2114 instance->data_size);
2122 check_tree (TreeInstance *instance,
2123 GVariantSerialised serialised)
2125 if (instance->info != serialised.type_info)
2128 if (instance->data_size == 0)
2129 /* is a container */
2133 if (g_variant_serialised_n_children (serialised) !=
2134 instance->n_children)
2137 for (i = 0; i < instance->n_children; i++)
2139 GVariantSerialised child;
2140 gpointer data = NULL;
2143 child = g_variant_serialised_get_child (serialised, i);
2144 if (child.size && child.data == NULL)
2145 child.data = data = g_malloc0 (child.size);
2146 ok = check_tree (instance->children[i], child);
2147 g_variant_type_info_unref (child.type_info);
2159 switch (instance->data_size)
2162 g_assert (serialised.size == 1);
2163 return *(guint8 *) serialised.data ==
2164 (guint8) instance->data.integer;
2167 g_assert (serialised.size == 2);
2168 return *(guint16 *) serialised.data ==
2169 (guint16) instance->data.integer;
2172 g_assert (serialised.size == 4);
2173 return *(guint32 *) serialised.data ==
2174 (guint32) instance->data.integer;
2177 g_assert (serialised.size == 8);
2178 return *(guint64 *) serialised.data ==
2179 (guint64) instance->data.integer;
2182 if (serialised.size != instance->data_size)
2185 return memcmp (serialised.data,
2186 instance->data.string,
2187 instance->data_size) == 0;
2193 serialise_tree (TreeInstance *tree,
2194 GVariantSerialised *serialised)
2196 GVariantSerialised empty = { };
2198 *serialised = empty;
2199 tree_filler (serialised, tree);
2200 serialised->data = g_malloc (serialised->size);
2201 tree_filler (serialised, tree);
2205 test_byteswap (void)
2207 GVariantSerialised one, two;
2210 tree = tree_instance_new (NULL, 3);
2211 serialise_tree (tree, &one);
2213 i_am_writing_byteswapped = TRUE;
2214 serialise_tree (tree, &two);
2215 i_am_writing_byteswapped = FALSE;
2217 g_variant_serialised_byteswap (two);
2219 g_assert_cmpint (one.size, ==, two.size);
2220 g_assert (memcmp (one.data, two.data, one.size) == 0);
2222 tree_instance_free (tree);
2228 test_byteswaps (void)
2232 for (i = 0; i < 200; i++)
2235 g_variant_type_info_assert_no_infos ();
2239 test_fuzz (gdouble *fuzziness)
2241 GVariantSerialised serialised;
2244 /* make an instance */
2245 tree = tree_instance_new (NULL, 3);
2248 serialise_tree (tree, &serialised);
2250 g_assert (g_variant_serialised_is_normal (serialised));
2251 g_assert (check_tree (tree, serialised));
2253 if (serialised.size)
2255 gboolean fuzzed = FALSE;
2262 for (i = 0; i < serialised.size; i++)
2263 if (randomly (*fuzziness))
2265 serialised.data[i] += g_test_rand_int_range (1, 256);
2270 /* at least one byte in the serialised data has changed.
2272 * this means that at least one of the following is true:
2274 * - the serialised data now represents a different value:
2275 * check_tree() will return FALSE
2277 * - the serialised data is in non-normal form:
2278 * g_variant_serialiser_is_normal() will return FALSE
2280 * we always do both checks to increase exposure of the serialiser
2283 a = g_variant_serialised_is_normal (serialised);
2284 b = check_tree (tree, serialised);
2286 g_assert (!a || !b);
2289 tree_instance_free (tree);
2290 g_free (serialised.data);
2295 test_fuzzes (gpointer data)
2300 fuzziness = GPOINTER_TO_INT (data) / 100.;
2302 for (i = 0; i < 200; i++)
2303 test_fuzz (&fuzziness);
2305 g_variant_type_info_assert_no_infos ();
2309 tree_instance_get_gvariant (TreeInstance *tree)
2311 const GVariantType *type;
2314 type = (GVariantType *) g_variant_type_info_get_type_string (tree->info);
2316 switch (g_variant_type_info_get_type_char (tree->info))
2318 case G_VARIANT_TYPE_INFO_CHAR_MAYBE:
2320 const GVariantType *child_type;
2323 if (tree->n_children)
2324 child = tree_instance_get_gvariant (tree->children[0]);
2328 child_type = g_variant_type_element (type);
2330 if (child != NULL && randomly (0.5))
2333 result = g_variant_new_maybe (child_type, child);
2337 case G_VARIANT_TYPE_INFO_CHAR_ARRAY:
2339 const GVariantType *child_type;
2340 GVariant **children;
2343 children = g_new (GVariant *, tree->n_children);
2344 for (i = 0; i < tree->n_children; i++)
2345 children[i] = tree_instance_get_gvariant (tree->children[i]);
2347 child_type = g_variant_type_element (type);
2349 if (i > 0 && randomly (0.5))
2352 result = g_variant_new_array (child_type, children, tree->n_children);
2357 case G_VARIANT_TYPE_INFO_CHAR_TUPLE:
2359 GVariant **children;
2362 children = g_new (GVariant *, tree->n_children);
2363 for (i = 0; i < tree->n_children; i++)
2364 children[i] = tree_instance_get_gvariant (tree->children[i]);
2366 result = g_variant_new_tuple (children, tree->n_children);
2371 case G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY:
2373 GVariant *key, *val;
2375 g_assert (tree->n_children == 2);
2377 key = tree_instance_get_gvariant (tree->children[0]);
2378 val = tree_instance_get_gvariant (tree->children[1]);
2380 result = g_variant_new_dict_entry (key, val);
2384 case G_VARIANT_TYPE_INFO_CHAR_VARIANT:
2388 g_assert (tree->n_children == 1);
2390 value = tree_instance_get_gvariant (tree->children[0]);
2391 result = g_variant_new_variant (value);
2396 result = g_variant_new_boolean (tree->data.integer > 0);
2400 result = g_variant_new_byte (tree->data.integer);
2404 result = g_variant_new_int16 (tree->data.integer);
2408 result = g_variant_new_uint16 (tree->data.integer);
2412 result = g_variant_new_int32 (tree->data.integer);
2416 result = g_variant_new_uint32 (tree->data.integer);
2420 result = g_variant_new_int64 (tree->data.integer);
2424 result = g_variant_new_uint64 (tree->data.integer);
2428 result = g_variant_new_handle (tree->data.integer);
2432 result = g_variant_new_double (tree->data.floating);
2436 result = g_variant_new_string (tree->data.string);
2440 result = g_variant_new_object_path (tree->data.string);
2444 result = g_variant_new_signature (tree->data.string);
2448 g_assert_not_reached ();
2455 tree_instance_check_gvariant (TreeInstance *tree,
2458 const GVariantType *type;
2460 type = (GVariantType *) g_variant_type_info_get_type_string (tree->info);
2461 g_assert (g_variant_is_of_type (value, type));
2463 switch (g_variant_type_info_get_type_char (tree->info))
2465 case G_VARIANT_TYPE_INFO_CHAR_MAYBE:
2470 child = g_variant_get_maybe (value);
2472 if (child != NULL && tree->n_children == 1)
2473 equal = tree_instance_check_gvariant (tree->children[0], child);
2474 else if (child == NULL && tree->n_children == 0)
2480 g_variant_unref (child);
2486 case G_VARIANT_TYPE_INFO_CHAR_ARRAY:
2487 case G_VARIANT_TYPE_INFO_CHAR_TUPLE:
2488 case G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY:
2492 if (g_variant_n_children (value) != tree->n_children)
2495 for (i = 0; i < tree->n_children; i++)
2500 child = g_variant_get_child_value (value, i);
2501 equal = tree_instance_check_gvariant (tree->children[i], child);
2502 g_variant_unref (child);
2512 case G_VARIANT_TYPE_INFO_CHAR_VARIANT:
2514 const gchar *str1, *str2;
2518 child = g_variant_get_variant (value);
2519 str1 = g_variant_get_type_string (child);
2520 str2 = g_variant_type_info_get_type_string (tree->children[0]->info);
2521 /* GVariant only keeps one copy of type strings around */
2522 equal = str1 == str2 &&
2523 tree_instance_check_gvariant (tree->children[0], child);
2525 g_variant_unref (child);
2532 return g_variant_get_boolean (value) == tree->data.integer;
2535 return g_variant_get_byte (value) == (guchar) tree->data.integer;
2538 return g_variant_get_int16 (value) == (gint16) tree->data.integer;
2541 return g_variant_get_uint16 (value) == (guint16) tree->data.integer;
2544 return g_variant_get_int32 (value) == (gint32) tree->data.integer;
2547 return g_variant_get_uint32 (value) == (guint32) tree->data.integer;
2550 return g_variant_get_int64 (value) == (gint64) tree->data.integer;
2553 return g_variant_get_uint64 (value) == (guint64) tree->data.integer;
2556 return g_variant_get_handle (value) == (gint32) tree->data.integer;
2560 gdouble floating = g_variant_get_double (value);
2562 return memcmp (&floating, &tree->data.floating, sizeof floating) == 0;
2568 return strcmp (g_variant_get_string (value, NULL),
2569 tree->data.string) == 0;
2572 g_assert_not_reached ();
2577 tree_instance_build_gvariant (TreeInstance *tree,
2578 GVariantBuilder *builder,
2581 const GVariantType *type;
2583 type = (GVariantType *) g_variant_type_info_get_type_string (tree->info);
2585 if (g_variant_type_is_container (type))
2589 /* force GVariantBuilder to guess the type half the time */
2590 if (guess_ok && randomly (0.5))
2592 if (g_variant_type_is_array (type) && tree->n_children)
2593 type = G_VARIANT_TYPE_ARRAY;
2595 if (g_variant_type_is_maybe (type) && tree->n_children)
2596 type = G_VARIANT_TYPE_MAYBE;
2598 if (g_variant_type_is_tuple (type))
2599 type = G_VARIANT_TYPE_TUPLE;
2601 if (g_variant_type_is_dict_entry (type))
2602 type = G_VARIANT_TYPE_DICT_ENTRY;
2607 g_variant_builder_open (builder, type);
2609 for (i = 0; i < tree->n_children; i++)
2610 tree_instance_build_gvariant (tree->children[i], builder, guess_ok);
2612 g_variant_builder_close (builder);
2615 g_variant_builder_add_value (builder, tree_instance_get_gvariant (tree));
2620 tree_instance_check_iter (TreeInstance *tree,
2625 value = g_variant_iter_next_value (iter);
2627 if (g_variant_is_container (value))
2631 iter = g_variant_iter_new (value);
2632 g_variant_unref (value);
2634 if (g_variant_iter_n_children (iter) != tree->n_children)
2636 g_variant_iter_free (iter);
2640 for (i = 0; i < tree->n_children; i++)
2641 if (!tree_instance_check_iter (tree->children[i], iter))
2643 g_variant_iter_free (iter);
2647 g_assert (g_variant_iter_next_value (iter) == NULL);
2648 g_variant_iter_free (iter);
2657 equal = tree_instance_check_gvariant (tree, value);
2658 g_variant_unref (value);
2665 test_container (void)
2671 tree = tree_instance_new (NULL, 3);
2672 value = g_variant_ref_sink (tree_instance_get_gvariant (tree));
2674 s1 = g_variant_print (value, TRUE);
2675 g_assert (tree_instance_check_gvariant (tree, value));
2677 g_variant_get_data (value);
2679 s2 = g_variant_print (value, TRUE);
2680 g_assert (tree_instance_check_gvariant (tree, value));
2682 g_assert_cmpstr (s1, ==, s2);
2684 if (g_variant_is_container (value))
2686 GVariantBuilder builder;
2692 g_variant_builder_init (&builder, G_VARIANT_TYPE_VARIANT);
2693 tree_instance_build_gvariant (tree, &builder, TRUE);
2694 built = g_variant_builder_end (&builder);
2695 g_variant_ref_sink (built);
2696 g_variant_get_data (built);
2697 val = g_variant_get_variant (built);
2699 s3 = g_variant_print (val, TRUE);
2700 g_assert_cmpstr (s1, ==, s3);
2702 g_variant_iter_init (&iter, built);
2703 g_assert (tree_instance_check_iter (tree, &iter));
2704 g_assert (g_variant_iter_next_value (&iter) == NULL);
2706 g_variant_unref (built);
2707 g_variant_unref (val);
2711 tree_instance_free (tree);
2712 g_variant_unref (value);
2720 const gchar invalid[] = "hello\xffworld";
2723 /* ensure that the test data is not valid utf8... */
2724 g_assert (!g_utf8_validate (invalid, -1, NULL));
2726 /* load the data untrusted */
2727 value = g_variant_new_from_data (G_VARIANT_TYPE_STRING,
2728 invalid, sizeof invalid,
2731 /* ensure that the problem is caught and we get valid UTF-8 */
2732 g_assert (g_utf8_validate (g_variant_get_string (value, NULL), -1, NULL));
2733 g_variant_unref (value);
2736 /* now load it trusted */
2737 value = g_variant_new_from_data (G_VARIANT_TYPE_STRING,
2738 invalid, sizeof invalid,
2741 /* ensure we get the invalid data (ie: make sure that time wasn't
2742 * wasted on validating data that was marked as trusted)
2744 g_assert (g_variant_get_string (value, NULL) == invalid);
2745 g_variant_unref (value);
2749 test_containers (void)
2753 for (i = 0; i < 100; i++)
2758 g_variant_type_info_assert_no_infos ();
2762 test_format_strings (void)
2767 g_assert (g_variant_format_string_scan ("i", NULL, &end) && *end == '\0');
2768 g_assert (g_variant_format_string_scan ("@i", NULL, &end) && *end == '\0');
2769 g_assert (g_variant_format_string_scan ("@ii", NULL, &end) && *end == 'i');
2770 g_assert (g_variant_format_string_scan ("^a&s", NULL, &end) && *end == '\0');
2771 g_assert (g_variant_format_string_scan ("(^as)", NULL, &end) &&
2773 g_assert (!g_variant_format_string_scan ("(^s)", NULL, &end));
2774 g_assert (!g_variant_format_string_scan ("(^a)", NULL, &end));
2775 g_assert (!g_variant_format_string_scan ("(z)", NULL, &end));
2776 g_assert (!g_variant_format_string_scan ("az", NULL, &end));
2777 g_assert (!g_variant_format_string_scan ("{**}", NULL, &end));
2778 g_assert (!g_variant_format_string_scan ("{@**}", NULL, &end));
2779 g_assert (g_variant_format_string_scan ("{@y*}", NULL, &end) &&
2781 g_assert (g_variant_format_string_scan ("{yv}", NULL, &end) &&
2783 g_assert (!g_variant_format_string_scan ("{&?v}", NULL, &end));
2784 g_assert (g_variant_format_string_scan ("{@?v}", NULL, &end) &&
2786 g_assert (!g_variant_format_string_scan ("{&@sv}", NULL, &end));
2787 g_assert (!g_variant_format_string_scan ("{@&sv}", NULL, &end));
2788 g_assert (g_variant_format_string_scan ("{&sv}", NULL, &end) &&
2790 g_assert (!g_variant_format_string_scan ("{vv}", NULL, &end));
2791 g_assert (!g_variant_format_string_scan ("{y}", NULL, &end));
2792 g_assert (!g_variant_format_string_scan ("{yyy}", NULL, &end));
2793 g_assert (!g_variant_format_string_scan ("{ya}", NULL, &end));
2794 g_assert (g_variant_format_string_scan ("&s", NULL, &end) && *end == '\0');
2795 g_assert (!g_variant_format_string_scan ("&as", NULL, &end));
2796 g_assert (!g_variant_format_string_scan ("@z", NULL, &end));
2797 g_assert (!g_variant_format_string_scan ("az", NULL, &end));
2798 g_assert (!g_variant_format_string_scan ("a&s", NULL, &end));
2800 type = g_variant_format_string_scan_type ("mm(@xy^a&s*?@?)", NULL, &end);
2801 g_assert (type && *end == '\0');
2802 g_assert (g_variant_type_equal (type, G_VARIANT_TYPE ("mm(xyas*?\?)")));
2803 g_variant_type_free (type);
2805 type = g_variant_format_string_scan_type ("mm(@xy^a&*?@?)", NULL, NULL);
2806 g_assert (type == NULL);
2810 exit_on_abort (int signal)
2816 do_failed_test (const gchar *pattern)
2818 if (g_test_trap_fork (1000000, G_TEST_TRAP_SILENCE_STDERR))
2820 signal (SIGABRT, exit_on_abort);
2824 g_test_trap_assert_failed ();
2825 g_test_trap_assert_stderr (pattern);
2831 test_invalid_varargs (void)
2833 if (do_failed_test ("*GVariant format string*"))
2835 g_variant_new ("z");
2839 if (do_failed_test ("*valid GVariant format string as a prefix*"))
2843 g_variant_new_va ("z", &end, NULL);
2847 if (do_failed_test ("*type of `q' but * has a type of `y'*"))
2849 g_variant_get (g_variant_new ("y", 'a'), "q");
2855 check_and_free (GVariant *value,
2858 gchar *valstr = g_variant_print (value, FALSE);
2859 g_assert_cmpstr (str, ==, valstr);
2860 g_variant_unref (value);
2868 GVariantBuilder array;
2870 g_variant_builder_init (&array, G_VARIANT_TYPE_ARRAY);
2871 g_variant_builder_add (&array, "{sv}", "size",
2872 g_variant_new ("(ii)", 800, 600));
2873 g_variant_builder_add (&array, "{sv}", "title",
2874 g_variant_new_string ("Test case"));
2875 g_variant_builder_add_value (&array,
2876 g_variant_new_dict_entry (g_variant_new_string ("temperature"),
2877 g_variant_new_variant (
2878 g_variant_new_double (37.5))));
2879 check_and_free (g_variant_new ("(ma{sv}m(a{sv})ma{sv}ii)",
2880 NULL, FALSE, NULL, &array, 7777, 8888),
2881 "(nothing, nothing, {'size': <(800, 600)>, "
2882 "'title': <'Test case'>, "
2883 "'temperature': <37.5>}, "
2886 check_and_free (g_variant_new ("(imimimmimmimmi)",
2893 "(123, nothing, 123, nothing, just nothing, 123)");
2895 check_and_free (g_variant_new ("(ybnixd)",
2896 'a', 1, 22, 33, (guint64) 44, 5.5),
2897 "(0x61, true, 22, 33, 44, 5.5)");
2899 check_and_free (g_variant_new ("(@y?*rv)",
2900 g_variant_new ("y", 'a'),
2901 g_variant_new ("y", 'b'),
2902 g_variant_new ("y", 'c'),
2903 g_variant_new ("(y)", 'd'),
2904 g_variant_new ("y", 'e')),
2905 "(0x61, 0x62, 0x63, (0x64,), <byte 0x65>)");
2909 GVariantBuilder array;
2916 g_variant_builder_init (&array, G_VARIANT_TYPE_ARRAY);
2917 for (i = 0; i < 100; i++)
2919 number = g_strdup_printf ("%d", i);
2920 g_variant_builder_add (&array, "s", number);
2924 value = g_variant_builder_end (&array);
2925 g_variant_iter_init (&iter, value);
2928 while (g_variant_iter_loop (&iter, "s", &number))
2930 gchar *check = g_strdup_printf ("%d", i++);
2931 g_assert_cmpstr (number, ==, check);
2934 g_assert (number == NULL);
2935 g_assert (i == 100);
2937 g_variant_unref (value);
2939 g_variant_builder_init (&array, G_VARIANT_TYPE_ARRAY);
2940 for (i = 0; i < 100; i++)
2941 g_variant_builder_add (&array, "mi", i % 2 == 0, i);
2942 value = g_variant_builder_end (&array);
2945 g_variant_iter_init (&iter, value);
2946 while (g_variant_iter_loop (&iter, "mi", NULL, &val))
2947 g_assert (val == i++ || val == 0);
2948 g_assert (i == 100);
2951 g_variant_iter_init (&iter, value);
2952 while (g_variant_iter_loop (&iter, "mi", &just, &val))
2959 g_assert (val == this);
2964 g_assert (val == 0);
2967 g_assert (i == 100);
2969 g_variant_unref (value);
2973 const gchar *strvector[] = {"/hello", "/world", NULL};
2974 const gchar *test_strs[] = {"/foo", "/bar", "/baz" };
2975 GVariantBuilder builder;
2976 GVariantIter *array;
2984 g_variant_builder_init (&builder, G_VARIANT_TYPE ("ao"));
2985 g_variant_builder_add (&builder, "o", "/foo");
2986 g_variant_builder_add (&builder, "o", "/bar");
2987 g_variant_builder_add (&builder, "o", "/baz");
2988 value = g_variant_new("(ao^ao^a&o)", &builder, strvector, strvector);
2989 g_variant_iter_init (&tuple, value);
2990 g_variant_iter_next (&tuple, "ao", &array);
2993 while (g_variant_iter_loop (array, "o", &str))
2994 g_assert_cmpstr (str, ==, test_strs[i++]);
2997 g_variant_iter_free (array);
3000 g_variant_iter_init (&tuple, value);
3001 g_variant_iter_next (&tuple, "ao", &array);
3004 while (g_variant_iter_loop (array, "&o", &str))
3005 g_assert_cmpstr (str, ==, test_strs[i++]);
3008 g_variant_iter_free (array);
3010 g_variant_iter_next (&tuple, "^a&o", &strv);
3011 g_variant_iter_next (&tuple, "^ao", &my_strv);
3013 g_assert_cmpstr (strv[0], ==, "/hello");
3014 g_assert_cmpstr (strv[1], ==, "/world");
3015 g_assert (strv[2] == NULL);
3016 g_assert_cmpstr (my_strv[0], ==, "/hello");
3017 g_assert_cmpstr (my_strv[1], ==, "/world");
3018 g_assert (my_strv[2] == NULL);
3020 g_variant_unref (value);
3021 g_strfreev (my_strv);
3026 const gchar *strvector[] = { "i", "ii", "iii", "iv", "v", "vi", NULL };
3027 GVariantBuilder builder;
3036 g_variant_builder_init (&builder, G_VARIANT_TYPE ("aag"));
3037 g_variant_builder_open (&builder, G_VARIANT_TYPE ("ag"));
3038 for (i = 0; i < 6; i++)
3040 g_variant_builder_add (&builder, "g", strvector[i]);
3042 g_variant_builder_add (&builder, "&g", strvector[i]);
3043 g_variant_builder_close (&builder);
3044 g_variant_builder_add (&builder, "^ag", strvector);
3045 g_variant_builder_add (&builder, "^ag", strvector);
3046 value = g_variant_new ("aag", &builder);
3048 g_variant_iter_init (&iter, value);
3049 while (g_variant_iter_loop (&iter, "^ag", &strv))
3050 for (i = 0; i < 6; i++)
3051 g_assert_cmpstr (strv[i], ==, strvector[i]);
3053 g_variant_iter_init (&iter, value);
3054 while (g_variant_iter_loop (&iter, "^a&g", &strv))
3055 for (i = 0; i < 6; i++)
3056 g_assert_cmpstr (strv[i], ==, strvector[i]);
3058 g_variant_iter_init (&iter, value);
3059 while (g_variant_iter_loop (&iter, "ag", &i2))
3064 while (g_variant_iter_loop (i2, "g", &str))
3065 g_assert_cmpstr (str, ==, strvector[i++]);
3069 g_variant_iter_init (&iter, value);
3070 i3 = g_variant_iter_copy (&iter);
3071 while (g_variant_iter_loop (&iter, "@ag", &sub))
3073 gchar *str = g_variant_print (sub, TRUE);
3074 g_assert_cmpstr (str, ==,
3075 "[signature 'i', 'ii', 'iii', 'iv', 'v', 'vi']");
3079 if (do_failed_test ("*NULL has already been returned*"))
3081 g_variant_iter_next_value (&iter);
3086 while (g_variant_iter_loop (i3, "*", &sub))
3088 gchar *str = g_variant_print (sub, TRUE);
3089 g_assert_cmpstr (str, ==,
3090 "[signature 'i', 'ii', 'iii', 'iv', 'v', 'vi']");
3094 g_variant_iter_free (i3);
3096 for (i = 0; i < g_variant_n_children (value); i++)
3100 g_variant_get_child (value, i, "*", &sub);
3102 for (j = 0; j < g_variant_n_children (sub); j++)
3104 const gchar *str = NULL;
3107 g_variant_get_child (sub, j, "&g", &str);
3108 g_assert_cmpstr (str, ==, strvector[j]);
3110 cval = g_variant_get_child_value (sub, j);
3111 g_variant_get (cval, "&g", &str);
3112 g_assert_cmpstr (str, ==, strvector[j]);
3113 g_variant_unref (cval);
3116 g_variant_unref (sub);
3119 g_variant_unref (value);
3138 /* test all 'nothing' */
3139 value = g_variant_new ("(mymbmnmqmimumxmtmhmdmv)",
3142 FALSE, (gint16) 123,
3143 FALSE, (guint16) 123,
3144 FALSE, (gint32) 123,
3145 FALSE, (guint32) 123,
3146 FALSE, (gint64) 123,
3147 FALSE, (guint64) 123,
3149 FALSE, (gdouble) 37.5,
3153 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3167 memset (justs, 1, sizeof justs);
3168 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3180 g_assert (!(justs[0] || justs[1] || justs[2] || justs[3] || justs[4] ||
3181 justs[5] || justs[6] || justs[7] || justs[8] || justs[9]));
3184 memset (justs, 1, sizeof justs);
3185 byteval = i16val = u16val = i32val = u32val = i64val = u64val = hval = 88;
3189 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3190 &justs[0], &byteval,
3201 g_assert (!(justs[0] || justs[1] || justs[2] || justs[3] || justs[4] ||
3202 justs[5] || justs[6] || justs[7] || justs[8] || justs[9]));
3203 g_assert (byteval == '\0' && bval == FALSE);
3204 g_assert (i16val == 0 && u16val == 0 && i32val == 0 &&
3205 u32val == 0 && i64val == 0 && u64val == 0 &&
3206 hval == 0 && dval == 0.0);
3207 g_assert (vval == NULL);
3210 byteval = i16val = u16val = i32val = u32val = i64val = u64val = hval = 88;
3214 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3226 g_assert (byteval == '\0' && bval == FALSE);
3227 g_assert (i16val == 0 && u16val == 0 && i32val == 0 &&
3228 u32val == 0 && i64val == 0 && u64val == 0 &&
3229 hval == 0 && dval == 0.0);
3230 g_assert (vval == NULL);
3232 g_variant_unref (value);
3235 /* test all 'just' */
3236 value = g_variant_new ("(mymbmnmqmimumxmtmhmdmv)",
3240 TRUE, (guint16) 123,
3242 TRUE, (guint32) 123,
3244 TRUE, (guint64) 123,
3246 TRUE, (gdouble) 37.5,
3247 g_variant_new ("()"));
3250 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3264 memset (justs, 0, sizeof justs);
3265 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3277 g_assert (justs[0] && justs[1] && justs[2] && justs[3] && justs[4] &&
3278 justs[5] && justs[6] && justs[7] && justs[8] && justs[9]);
3281 memset (justs, 0, sizeof justs);
3282 byteval = i16val = u16val = i32val = u32val = i64val = u64val = hval = 88;
3286 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3287 &justs[0], &byteval,
3298 g_assert (justs[0] && justs[1] && justs[2] && justs[3] && justs[4] &&
3299 justs[5] && justs[6] && justs[7] && justs[8] && justs[9]);
3300 g_assert (byteval == 'a' && bval == TRUE);
3301 g_assert (i16val == 123 && u16val == 123 && i32val == 123 &&
3302 u32val == 123 && i64val == 123 && u64val == 123 &&
3303 hval == -1 && dval == 37.5);
3304 g_assert (g_variant_is_of_type (vval, G_VARIANT_TYPE_UNIT));
3305 g_variant_unref (vval);
3308 byteval = i16val = u16val = i32val = u32val = i64val = u64val = hval = 88;
3312 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3324 g_assert (byteval == 'a' && bval == TRUE);
3325 g_assert (i16val == 123 && u16val == 123 && i32val == 123 &&
3326 u32val == 123 && i64val == 123 && u64val == 123 &&
3327 hval == -1 && dval == 37.5);
3328 g_assert (g_variant_is_of_type (vval, G_VARIANT_TYPE_UNIT));
3329 g_variant_unref (vval);
3331 g_variant_unref (value);
3334 g_variant_type_info_assert_no_infos ();
3338 hash_get (GVariant *value,
3339 const gchar *format,
3342 const gchar *endptr = NULL;
3346 hash = g_str_has_suffix (format, "#");
3348 va_start (ap, format);
3349 g_variant_get_va (value, format, hash ? &endptr : NULL, &ap);
3353 g_assert (*endptr == '#');
3357 hash_new (const gchar *format,
3360 const gchar *endptr = NULL;
3365 hash = g_str_has_suffix (format, "#");
3367 va_start (ap, format);
3368 value = g_variant_new_va (format, hash ? &endptr : NULL, &ap);
3372 g_assert (*endptr == '#');
3384 value = hash_new ("i", 234);
3385 hash_get (value, "i", &x);
3386 g_assert (x == 234);
3387 g_variant_unref (value);
3390 value = hash_new ("i#", 234);
3391 hash_get (value, "i#", &x);
3392 g_assert (x == 234);
3393 g_variant_unref (value);
3395 g_variant_type_info_assert_no_infos ();
3399 test_builder_memory (void)
3401 GVariantBuilder *hb;
3404 hb = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
3405 g_variant_builder_open (hb, G_VARIANT_TYPE_ARRAY);
3406 g_variant_builder_open (hb, G_VARIANT_TYPE_ARRAY);
3407 g_variant_builder_open (hb, G_VARIANT_TYPE_ARRAY);
3408 g_variant_builder_add (hb, "s", "some value");
3409 g_variant_builder_ref (hb);
3410 g_variant_builder_unref (hb);
3411 g_variant_builder_unref (hb);
3413 hb = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
3414 g_variant_builder_unref (hb);
3416 hb = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
3417 g_variant_builder_clear (hb);
3418 g_variant_builder_unref (hb);
3420 g_variant_builder_init (&sb, G_VARIANT_TYPE_ARRAY);
3421 g_variant_builder_open (&sb, G_VARIANT_TYPE_ARRAY);
3422 g_variant_builder_open (&sb, G_VARIANT_TYPE_ARRAY);
3423 g_variant_builder_add (&sb, "s", "some value");
3424 g_variant_builder_clear (&sb);
3426 g_variant_type_info_assert_no_infos ();
3432 GVariant *items[4096];
3436 table = g_hash_table_new_full (g_variant_hash, g_variant_equal,
3437 (GDestroyNotify ) g_variant_unref,
3440 for (i = 0; i < G_N_ELEMENTS (items); i++)
3446 tree = tree_instance_new (NULL, 0);
3447 items[i] = tree_instance_get_gvariant (tree);
3448 tree_instance_free (tree);
3450 for (j = 0; j < i; j++)
3451 if (g_variant_equal (items[i], items[j]))
3453 g_variant_unref (items[i]);
3457 g_hash_table_insert (table,
3458 g_variant_ref_sink (items[i]),
3459 GINT_TO_POINTER (i));
3462 for (i = 0; i < G_N_ELEMENTS (items); i++)
3466 result = g_hash_table_lookup (table, items[i]);
3467 g_assert_cmpint (GPOINTER_TO_INT (result), ==, i);
3470 g_hash_table_unref (table);
3472 g_variant_type_info_assert_no_infos ();
3478 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
3479 # define native16(x) x, 0
3480 # define swapped16(x) 0, x
3482 # define native16(x) 0, x
3483 # define swapped16(x) x, 0
3485 /* all kinds of of crazy randomised testing already performed on the
3486 * byteswapper in the /gvariant/serialiser/byteswap test and all kinds
3487 * of crazy randomised testing performed against the serialiser
3488 * normalisation functions in the /gvariant/serialiser/fuzz/ tests.
3490 * just test a few simple cases here to make sure they each work
3492 guchar valid_data[] = { 'a', '\0', swapped16(66), 2,
3494 'b', '\0', swapped16(77), 2,
3496 guchar corrupt_data[] = { 'a', '\0', swapped16(66), 2,
3498 'b', '\0', swapped16(77), 2,
3500 GVariant *value, *swapped;
3501 gchar *string, *string2;
3505 value = g_variant_new_from_data (G_VARIANT_TYPE ("a(sn)"),
3506 valid_data, sizeof valid_data, TRUE,
3508 swapped = g_variant_byteswap (value);
3509 g_variant_unref (value);
3510 g_assert (g_variant_get_size (swapped) == 13);
3511 string = g_variant_print (swapped, FALSE);
3512 g_variant_unref (swapped);
3513 g_assert_cmpstr (string, ==, "[('a', 66), ('b', 77)]");
3516 /* untrusted but valid */
3517 value = g_variant_new_from_data (G_VARIANT_TYPE ("a(sn)"),
3518 valid_data, sizeof valid_data, FALSE,
3520 swapped = g_variant_byteswap (value);
3521 g_variant_unref (value);
3522 g_assert (g_variant_get_size (swapped) == 13);
3523 string = g_variant_print (swapped, FALSE);
3524 g_variant_unref (swapped);
3525 g_assert_cmpstr (string, ==, "[('a', 66), ('b', 77)]");
3528 /* untrusted, invalid */
3529 value = g_variant_new_from_data (G_VARIANT_TYPE ("a(sn)"),
3530 corrupt_data, sizeof corrupt_data, FALSE,
3532 string = g_variant_print (value, FALSE);
3533 swapped = g_variant_byteswap (value);
3534 g_variant_unref (value);
3535 g_assert (g_variant_get_size (swapped) == 13);
3536 value = g_variant_byteswap (swapped);
3537 g_variant_unref (swapped);
3538 string2 = g_variant_print (value, FALSE);
3539 g_assert (g_variant_get_size (value) == 13);
3540 g_variant_unref (value);
3541 g_assert_cmpstr (string, ==, string2);
3555 tree = tree_instance_new (NULL, 3);
3556 value = tree_instance_get_gvariant (tree);
3557 tree_instance_free (tree);
3559 pt = g_variant_print (value, TRUE);
3560 p = g_variant_print (value, FALSE);
3562 parsed = g_variant_parse (NULL, pt, NULL, NULL, NULL);
3563 res = g_variant_print (parsed, FALSE);
3564 g_assert_cmpstr (p, ==, res);
3565 g_variant_unref (parsed);
3568 parsed = g_variant_parse (g_variant_get_type (value), p,
3570 res = g_variant_print (parsed, TRUE);
3571 g_assert_cmpstr (pt, ==, res);
3572 g_variant_unref (parsed);
3575 g_variant_unref (value);
3585 for (i = 0; i < 100; i++)
3596 for (i = 0; i < 256; i++)
3599 val = g_variant_new_string (str);
3600 p = g_variant_print (val, FALSE);
3601 g_variant_unref (val);
3603 val = g_variant_parse (NULL, p, NULL, NULL, NULL);
3604 p2 = g_variant_print (val, FALSE);
3606 g_assert_cmpstr (str, ==, g_variant_get_string (val, NULL));
3607 g_assert_cmpstr (p, ==, p2);
3609 g_variant_unref (val);
3614 /* another mini test */
3619 value = g_variant_parse (G_VARIANT_TYPE_INT32, "1 2 3", NULL, &end, NULL);
3620 g_assert_cmpint (g_variant_get_int32 (value), ==, 1);
3621 /* make sure endptr returning works */
3622 g_assert_cmpstr (end, ==, " 2 3");
3623 g_variant_unref (value);
3626 g_variant_type_info_assert_no_infos ();
3630 test_parse_failures (void)
3632 const gchar *test[] = {
3633 "[1, 2,", "6:", "expected value",
3634 "", "0:", "expected value",
3635 "(1, 2,", "6:", "expected value",
3636 "<1", "2:", "expected `>'",
3637 "[]", "0-2:", "unable to infer",
3638 "(,", "1:", "expected value",
3639 "[4,'']", "1-2,3-5:", "common type",
3640 "[4, '', 5]", "1-2,4-6:", "common type",
3641 "['', 4, 5]", "1-3,5-6:", "common type",
3642 "[4, 5, '']", "1-2,7-9:", "common type",
3643 "[[4], [], ['']]", "1-4,10-14:", "common type",
3644 "[[], [4], ['']]", "5-8,10-14:", "common type",
3645 "just", "4:", "expected value",
3646 "nothing", "0-7:", "unable to infer",
3647 "just [4, '']", "6-7,9-11:", "common type",
3648 "[[4,'']]", "2-3,4-6:", "common type",
3649 "([4,''],)", "2-3,4-6:", "common type",
3651 "{}", "0-2:", "unable to infer",
3652 "{[1,2],[3,4]}", "0-13:", "basic types",
3653 "{[1,2]:[3,4]}", "0-13:", "basic types",
3654 "justt", "0-5:", "unknown keyword",
3655 "nothng", "0-6:", "unknown keyword",
3656 "uint33", "0-6:", "unknown keyword",
3657 "@mi just ''", "9-11:", "can not parse as",
3658 "@ai ['']", "5-7:", "can not parse as",
3659 "@(i) ('',)", "6-8:", "can not parse as",
3660 "[[], 5]", "1-3,5-6:", "common type",
3661 "[[5], 5]", "1-4,6-7:", "common type",
3662 "5 5", "2:", "expected end of input",
3663 "[5, [5, '']]", "5-6,8-10:", "common type",
3664 "@i just 5", "3-9:", "can not parse as",
3665 "@i nothing", "3-10:", "can not parse as",
3666 "@i []", "3-5:", "can not parse as",
3667 "@i ()", "3-5:", "can not parse as",
3668 "@ai (4,)", "4-8:", "can not parse as",
3669 "@(i) []", "5-7:", "can not parse as",
3670 "(5 5)", "3:", "expected `,'",
3671 "[5 5]", "3:", "expected `,' or `]'",
3672 "(5, 5 5)", "6:", "expected `,' or `)'",
3673 "[5, 5 5]", "6:", "expected `,' or `]'",
3674 "<@i []>", "4-6:", "can not parse as",
3675 "<[5 5]>", "4:", "expected `,' or `]'",
3676 "{[4,''],5}", "2-3,4-6:", "common type",
3677 "{5,[4,'']}", "4-5,6-8:", "common type",
3678 "@i {1,2}", "3-8:", "can not parse as",
3679 "{@i '', 5}", "4-6:", "can not parse as",
3680 "{5, @i ''}", "7-9:", "can not parse as",
3681 "@ai {}", "4-6:", "can not parse as",
3682 "{@i '': 5}", "4-6:", "can not parse as",
3683 "{5: @i ''}", "7-9:", "can not parse as",
3684 "{<4,5}", "3:", "expected `>'",
3685 "{4,<5}", "5:", "expected `>'",
3686 "{4,5,6}", "4:", "expected `}'",
3687 "{5 5}", "3:", "expected `:' or `,'",
3688 "{4: 5: 6}", "5:", "expected `,' or `}'",
3689 "{4:5,<6:7}", "7:", "expected `>'",
3690 "{4:5,6:<7}", "9:", "expected `>'",
3691 "{4:5,6 7}", "7:", "expected `:'",
3692 "@o 'foo'", "3-8:", "object path",
3693 "@g 'zzz'", "3-8:", "signature",
3694 "@i true", "3-7:", "can not parse as",
3695 "@z 4", "0-2:", "invalid type",
3696 "@a* []", "0-3:", "definite",
3697 "@ai [3 3]", "7:", "expected `,' or `]'",
3698 "18446744073709551616", "0-20:", "too big for any type",
3699 "-18446744073709551616", "0-21:", "too big for any type",
3700 "byte 256", "5-8:", "out of range for type",
3701 "byte -1", "5-7:", "out of range for type",
3702 "int16 32768", "6-11:", "out of range for type",
3703 "int16 -32769", "6-12:", "out of range for type",
3704 "uint16 -1", "7-9:", "out of range for type",
3705 "uint16 65536", "7-12:", "out of range for type",
3706 "2147483648", "0-10:", "out of range for type",
3707 "-2147483649", "0-11:", "out of range for type",
3708 "uint32 -1", "7-9:", "out of range for type",
3709 "uint32 4294967296", "7-17:", "out of range for type",
3710 "@x 9223372036854775808", "3-22:", "out of range for type",
3711 "@x -9223372036854775809", "3-23:", "out of range for type",
3712 "@t -1", "3-5:", "out of range for type",
3713 "@t 18446744073709551616", "3-23:", "too big for any type",
3714 "handle 2147483648", "7-17:", "out of range for type",
3715 "handle -2147483649", "7-18:", "out of range for type",
3716 "1.798e308", "0-9:", "too big for any type",
3717 "37.5a488", "4-5:", "invalid character",
3718 "0x7ffgf", "5-6:", "invalid character",
3719 "07758", "4-5:", "invalid character",
3720 "123a5", "3-4:", "invalid character",
3721 "@ai 123", "4-7:", "can not parse as",
3722 "'\"\\'", "0-4:", "unterminated string",
3723 "'\"\\'\\", "0-5:", "unterminated string",
3724 "boolean 4", "8-9:", "can not parse as",
3725 "int32 true", "6-10:", "can not parse as",
3726 "[double 5, int32 5]", "1-9,11-18:", "common type",
3727 "string 4", "7-8:", "can not parse as"
3731 for (i = 0; i < G_N_ELEMENTS (test); i += 3)
3733 GError *error = NULL;
3736 value = g_variant_parse (NULL, test[i], NULL, NULL, &error);
3737 g_assert (value == NULL);
3739 if (!strstr (error->message, test[i+2]))
3740 g_error ("test %d: Can't find `%s' in `%s'", i / 3,
3741 test[i+2], error->message);
3743 if (!g_str_has_prefix (error->message, test[i+1]))
3744 g_error ("test %d: Expected location `%s' in `%s'", i / 3,
3745 test[i+1], error->message);
3747 g_error_free (error);
3752 test_parse_positional (void)
3755 check_and_free (g_variant_new_parsed ("[('one', 1), (%s, 2),"
3756 " ('three', %i)]", "two", 3),
3757 "[('one', 1), ('two', 2), ('three', 3)]");
3758 value = g_variant_new_parsed ("[('one', 1), (%s, 2),"
3759 " ('three', %u)]", "two", 3);
3760 g_assert (g_variant_is_of_type (value, G_VARIANT_TYPE ("a(su)")));
3761 check_and_free (value, "[('one', 1), ('two', 2), ('three', 3)]");
3762 check_and_free (g_variant_new_parsed ("{%s:%i}", "one", 1), "{'one': 1}");
3764 if (do_failed_test ("*GVariant format string*"))
3766 g_variant_new_parsed ("%z");
3770 if (do_failed_test ("*can not parse as*"))
3772 g_variant_new_parsed ("uint32 %i", 2);
3776 if (do_failed_test ("*expected GVariant of type `i'*"))
3778 g_variant_new_parsed ("%@i", g_variant_new_uint32 (2));
3784 main (int argc, char **argv)
3788 g_test_init (&argc, &argv, NULL);
3790 g_test_add_func ("/gvariant/type", test_gvarianttype);
3791 g_test_add_func ("/gvariant/typeinfo", test_gvarianttypeinfo);
3792 g_test_add_func ("/gvariant/serialiser/maybe", test_maybes);
3793 g_test_add_func ("/gvariant/serialiser/array", test_arrays);
3794 g_test_add_func ("/gvariant/serialiser/tuple", test_tuples);
3795 g_test_add_func ("/gvariant/serialiser/variant", test_variants);
3796 g_test_add_func ("/gvariant/serialiser/strings", test_strings);
3797 g_test_add_func ("/gvariant/serialiser/byteswap", test_byteswaps);
3799 for (i = 1; i <= 20; i += 4)
3803 testname = g_strdup_printf ("/gvariant/serialiser/fuzz/%d%%", i);
3804 g_test_add_data_func (testname, GINT_TO_POINTER (i),
3805 (gpointer) test_fuzzes);
3809 g_test_add_func ("/gvariant/utf8", test_utf8);
3810 g_test_add_func ("/gvariant/containers", test_containers);
3811 g_test_add_func ("/gvariant/format-strings", test_format_strings);
3812 g_test_add_func ("/gvariant/invalid-varargs", test_invalid_varargs);
3813 g_test_add_func ("/gvariant/varargs", test_varargs);
3814 g_test_add_func ("/gvariant/valist", test_valist);
3815 g_test_add_func ("/gvariant/builder-memory", test_builder_memory);
3816 g_test_add_func ("/gvariant/hashing", test_hashing);
3817 g_test_add_func ("/gvariant/byteswap", test_gv_byteswap);
3818 g_test_add_func ("/gvariant/parser", test_parses);
3819 g_test_add_func ("/gvariant/parse-failures", test_parse_failures);
3820 g_test_add_func ("/gvariant/parse-positional", test_parse_positional);
3822 return g_test_run ();