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>
14 #include <glib/gvariant-internal.h>
19 #define BASIC "bynqiuxthdsog?"
20 #define N_BASIC (G_N_ELEMENTS (BASIC) - 1)
22 #define INVALIDS "cefjklpwz&@^$"
23 #define N_INVALIDS (G_N_ELEMENTS (INVALIDS) - 1)
25 /* see comment in gvariant-serialiser.c about this madness.
27 * we use this to get testing of non-strictly-aligned GVariant instances
28 * on machines that can tolerate it. it is necessary to support this
29 * because some systems have malloc() that returns non-8-aligned
30 * pointers. it is necessary to have special support in the tests
31 * because on most machines malloc() is 8-aligned.
33 #define ALIGN_BITS (sizeof (struct { char a; union { \
34 guint64 x; void *y; gdouble z; } b; }) - 9)
37 randomly (gdouble prob)
39 return g_test_rand_double_range (0, 1) < prob;
44 append_tuple_type_string (GString *, GString *, gboolean, gint);
46 /* append a random GVariantType to a GString
47 * append a description of the type to another GString
48 * return what the type is
51 append_type_string (GString *string,
56 if (!depth-- || randomly (0.3))
58 gchar b = BASIC[g_test_rand_int_range (0, N_BASIC - definite)];
59 g_string_append_c (string, b);
60 g_string_append_c (description, b);
65 return g_variant_type_copy (G_VARIANT_TYPE_BOOLEAN);
67 return g_variant_type_copy (G_VARIANT_TYPE_BYTE);
69 return g_variant_type_copy (G_VARIANT_TYPE_INT16);
71 return g_variant_type_copy (G_VARIANT_TYPE_UINT16);
73 return g_variant_type_copy (G_VARIANT_TYPE_INT32);
75 return g_variant_type_copy (G_VARIANT_TYPE_UINT32);
77 return g_variant_type_copy (G_VARIANT_TYPE_INT64);
79 return g_variant_type_copy (G_VARIANT_TYPE_UINT64);
81 return g_variant_type_copy (G_VARIANT_TYPE_HANDLE);
83 return g_variant_type_copy (G_VARIANT_TYPE_DOUBLE);
85 return g_variant_type_copy (G_VARIANT_TYPE_STRING);
87 return g_variant_type_copy (G_VARIANT_TYPE_OBJECT_PATH);
89 return g_variant_type_copy (G_VARIANT_TYPE_SIGNATURE);
91 return g_variant_type_copy (G_VARIANT_TYPE_BASIC);
93 g_assert_not_reached ();
100 switch (g_test_rand_int_range (0, definite ? 5 : 7))
104 GVariantType *element;
106 g_string_append_c (string, 'a');
107 g_string_append (description, "a of ");
108 element = append_type_string (string, description,
110 result = g_variant_type_new_array (element);
111 g_variant_type_free (element);
114 g_assert (g_variant_type_is_array (result));
119 GVariantType *element;
121 g_string_append_c (string, 'm');
122 g_string_append (description, "m of ");
123 element = append_type_string (string, description,
125 result = g_variant_type_new_maybe (element);
126 g_variant_type_free (element);
129 g_assert (g_variant_type_is_maybe (result));
133 result = append_tuple_type_string (string, description,
136 g_assert (g_variant_type_is_tuple (result));
141 GVariantType *key, *value;
143 g_string_append_c (string, '{');
144 g_string_append (description, "e of [");
145 key = append_type_string (string, description, definite, 0);
146 g_string_append (description, ", ");
147 value = append_type_string (string, description, definite, depth);
148 g_string_append_c (description, ']');
149 g_string_append_c (string, '}');
150 result = g_variant_type_new_dict_entry (key, value);
151 g_variant_type_free (key);
152 g_variant_type_free (value);
155 g_assert (g_variant_type_is_dict_entry (result));
159 g_string_append_c (string, 'v');
160 g_string_append_c (description, 'V');
161 result = g_variant_type_copy (G_VARIANT_TYPE_VARIANT);
162 g_assert (g_variant_type_equal (result, G_VARIANT_TYPE_VARIANT));
166 g_string_append_c (string, '*');
167 g_string_append_c (description, 'S');
168 result = g_variant_type_copy (G_VARIANT_TYPE_ANY);
169 g_assert (g_variant_type_equal (result, G_VARIANT_TYPE_ANY));
173 g_string_append_c (string, 'r');
174 g_string_append_c (description, 'R');
175 result = g_variant_type_copy (G_VARIANT_TYPE_TUPLE);
176 g_assert (g_variant_type_is_tuple (result));
180 g_assert_not_reached ();
187 static GVariantType *
188 append_tuple_type_string (GString *string,
189 GString *description,
193 GVariantType *result, *other_result;
194 GVariantType **types;
198 g_string_append_c (string, '(');
199 g_string_append (description, "t of [");
201 size = g_test_rand_int_range (0, 20);
202 types = g_new (GVariantType *, size + 1);
204 for (i = 0; i < size; i++)
206 types[i] = append_type_string (string, description, definite, depth);
209 g_string_append (description, ", ");
214 g_string_append_c (description, ']');
215 g_string_append_c (string, ')');
217 result = g_variant_type_new_tuple ((gpointer) types, size);
218 other_result = g_variant_type_new_tuple ((gpointer) types, -1);
219 g_assert (g_variant_type_equal (result, other_result));
220 g_variant_type_free (other_result);
221 for (i = 0; i < size; i++)
222 g_variant_type_free (types[i]);
228 /* given a valid type string, make it invalid */
230 invalid_mutation (const gchar *type_string)
232 gboolean have_parens, have_braces;
234 /* it's valid, so '(' implies ')' and same for '{' and '}' */
235 have_parens = strchr (type_string, '(') != NULL;
236 have_braces = strchr (type_string, '{') != NULL;
238 if (have_parens && have_braces && randomly (0.3))
240 /* swap a paren and a brace */
246 new = g_strdup (type_string);
256 /* count number of parens/braces */
257 while ((pp = strchr (pp + 1, p))) np++;
258 while ((bp = strchr (bp + 1, b))) nb++;
260 /* randomly pick one of each */
261 np = g_test_rand_int_range (0, np) + 1;
262 nb = g_test_rand_int_range (0, nb) + 1;
266 while (np--) pp = strchr (pp + 1, p);
267 while (nb--) bp = strchr (bp + 1, b);
270 g_assert (*bp == b && *pp == p);
277 if ((have_parens || have_braces) && randomly (0.3))
279 /* drop a paren/brace */
286 if (randomly (0.5)) p = '('; else p = ')';
288 if (randomly (0.5)) p = '{'; else p = '}';
290 new = g_strdup (type_string);
294 while ((pp = strchr (pp + 1, p))) np++;
295 np = g_test_rand_int_range (0, np) + 1;
297 while (np--) pp = strchr (pp + 1, p);
309 /* else, perform a random mutation at a random point */
317 /* insert a paren/brace */
319 if (randomly (0.5)) p = '('; else p = ')';
321 if (randomly (0.5)) p = '{'; else p = '}';
323 else if (randomly (0.5))
326 p = INVALIDS[g_test_rand_int_range (0, N_INVALIDS)];
335 length = strlen (type_string);
336 new = g_malloc (length + 2);
337 n = g_test_rand_int_range (0, length);
338 memcpy (new, type_string, n);
340 memcpy (new + n + 1, type_string + n, length - n);
341 new[length + 1] = '\0';
347 /* describe a type using the same language as is generated
348 * while generating the type with append_type_string
351 describe_type (const GVariantType *type)
355 if (g_variant_type_is_container (type))
357 g_assert (!g_variant_type_is_basic (type));
359 if (g_variant_type_is_array (type))
361 gchar *subtype = describe_type (g_variant_type_element (type));
362 result = g_strdup_printf ("a of %s", subtype);
365 else if (g_variant_type_is_maybe (type))
367 gchar *subtype = describe_type (g_variant_type_element (type));
368 result = g_strdup_printf ("m of %s", subtype);
371 else if (g_variant_type_is_tuple (type))
373 if (!g_variant_type_equal (type, G_VARIANT_TYPE_TUPLE))
375 const GVariantType *sub;
380 string = g_string_new ("t of [");
382 length = g_variant_type_n_items (type);
383 sub = g_variant_type_first (type);
384 for (i = 0; i < length; i++)
386 gchar *subtype = describe_type (sub);
387 g_string_append (string, subtype);
390 if ((sub = g_variant_type_next (sub)))
391 g_string_append (string, ", ");
393 g_assert (sub == NULL);
394 g_string_append_c (string, ']');
396 result = g_string_free (string, FALSE);
399 result = g_strdup ("R");
401 else if (g_variant_type_is_dict_entry (type))
403 gchar *key, *value, *key2, *value2;
405 key = describe_type (g_variant_type_key (type));
406 value = describe_type (g_variant_type_value (type));
407 key2 = describe_type (g_variant_type_first (type));
408 value2 = describe_type (
409 g_variant_type_next (g_variant_type_first (type)));
410 g_assert (g_variant_type_next (g_variant_type_next (
411 g_variant_type_first (type))) == NULL);
412 g_assert_cmpstr (key, ==, key2);
413 g_assert_cmpstr (value, ==, value2);
414 result = g_strjoin ("", "e of [", key, ", ", value, "]", NULL);
420 else if (g_variant_type_equal (type, G_VARIANT_TYPE_VARIANT))
422 result = g_strdup ("V");
425 g_assert_not_reached ();
429 if (g_variant_type_is_definite (type))
431 g_assert (g_variant_type_is_basic (type));
433 if (g_variant_type_equal (type, G_VARIANT_TYPE_BOOLEAN))
434 result = g_strdup ("b");
435 else if (g_variant_type_equal (type, G_VARIANT_TYPE_BYTE))
436 result = g_strdup ("y");
437 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT16))
438 result = g_strdup ("n");
439 else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT16))
440 result = g_strdup ("q");
441 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32))
442 result = g_strdup ("i");
443 else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT32))
444 result = g_strdup ("u");
445 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT64))
446 result = g_strdup ("x");
447 else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT64))
448 result = g_strdup ("t");
449 else if (g_variant_type_equal (type, G_VARIANT_TYPE_HANDLE))
450 result = g_strdup ("h");
451 else if (g_variant_type_equal (type, G_VARIANT_TYPE_DOUBLE))
452 result = g_strdup ("d");
453 else if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING))
454 result = g_strdup ("s");
455 else if (g_variant_type_equal (type, G_VARIANT_TYPE_OBJECT_PATH))
456 result = g_strdup ("o");
457 else if (g_variant_type_equal (type, G_VARIANT_TYPE_SIGNATURE))
458 result = g_strdup ("g");
460 g_assert_not_reached ();
464 if (g_variant_type_equal (type, G_VARIANT_TYPE_ANY))
466 result = g_strdup ("S");
468 else if (g_variant_type_equal (type, G_VARIANT_TYPE_BASIC))
470 result = g_strdup ("?");
473 g_assert_not_reached ();
480 /* given a type string, replace one of the indefinite type characters in
481 * it with a matching type (possibly the same type).
484 generate_subtype (const gchar *type_string)
486 GVariantType *replacement;
487 GString *result, *junk;
488 gint length, n = 0, l;
490 result = g_string_new (NULL);
491 junk = g_string_new (NULL);
493 /* count the number of indefinite type characters */
494 for (length = 0; type_string[length]; length++)
495 n += type_string[length] == 'r' ||
496 type_string[length] == '?' ||
497 type_string[length] == '*';
498 /* length now is strlen (type_string) */
500 /* pick one at random to replace */
501 n = g_test_rand_int_range (0, n) + 1;
505 while (n--) l += strcspn (type_string + l + 1, "r?*") + 1;
506 g_assert (type_string[l] == 'r' ||
507 type_string[l] == '?' ||
508 type_string[l] == '*');
510 /* store up to that point in a GString */
511 g_string_append_len (result, type_string, l);
513 /* then store the replacement in the GString */
514 if (type_string[l] == 'r')
515 replacement = append_tuple_type_string (result, junk, FALSE, 3);
517 else if (type_string[l] == '?')
518 replacement = append_type_string (result, junk, FALSE, 0);
520 else if (type_string[l] == '*')
521 replacement = append_type_string (result, junk, FALSE, 3);
524 g_assert_not_reached ();
526 /* ensure the replacement has the proper type */
527 g_assert (g_variant_type_is_subtype_of (replacement,
528 (gpointer) &type_string[l]));
530 /* store the rest from the original type string */
531 g_string_append (result, type_string + l + 1);
533 g_variant_type_free (replacement);
534 g_string_free (junk, TRUE);
536 return g_string_free (result, FALSE);
541 const GVariantType *type;
542 struct typestack *parent;
545 /* given an indefinite type string, replace one of the indefinite
546 * characters in it with a matching type and ensure that the result is a
547 * subtype of the original. repeat.
550 subtype_check (const gchar *type_string,
551 struct typestack *parent_ts)
553 struct typestack ts, *node;
557 subtype = generate_subtype (type_string);
559 ts.type = G_VARIANT_TYPE (subtype);
560 ts.parent = parent_ts;
562 for (node = &ts; node; node = node->parent)
564 /* this type should be a subtype of each parent type */
565 g_assert (g_variant_type_is_subtype_of (ts.type, node->type));
567 /* it should only be a supertype when it is exactly equal */
568 g_assert (g_variant_type_is_subtype_of (node->type, ts.type) ==
569 g_variant_type_equal (ts.type, node->type));
574 if (!g_variant_type_is_definite (ts.type) && depth < 5)
576 /* the type is still indefinite and we haven't repeated too many
577 * times. go once more.
580 subtype_check (subtype, &ts);
587 test_gvarianttype (void)
591 for (i = 0; i < 2000; i++)
593 GString *type_string, *description;
594 GVariantType *type, *other_type;
595 const GVariantType *ctype;
599 type_string = g_string_new (NULL);
600 description = g_string_new (NULL);
602 /* generate a random type, its type string and a description
604 * exercises type constructor functions and g_variant_type_copy()
606 type = append_type_string (type_string, description, FALSE, 6);
608 /* convert the type string to a type and ensure that it is equal
609 * to the one produced with the type constructor routines
611 ctype = G_VARIANT_TYPE (type_string->str);
612 g_assert (g_variant_type_equal (ctype, type));
613 g_assert (g_variant_type_is_subtype_of (ctype, type));
614 g_assert (g_variant_type_is_subtype_of (type, ctype));
616 /* check if the type is indefinite */
617 if (!g_variant_type_is_definite (type))
619 struct typestack ts = { type, NULL };
621 /* if it is indefinite, then replace one of the indefinite
622 * characters with a matching type and ensure that the result
623 * is a subtype of the original type. repeat.
625 subtype_check (type_string->str, &ts);
628 /* ensure that no indefinite characters appear */
629 g_assert (strcspn (type_string->str, "r?*") == type_string->len);
632 /* describe the type.
634 * exercises the type iterator interface
636 desc = describe_type (type);
638 /* make sure the description matches */
639 g_assert_cmpstr (desc, ==, description->str);
642 /* make an invalid mutation to the type and make sure the type
643 * validation routines catch it */
644 invalid = invalid_mutation (type_string->str);
645 g_assert (g_variant_type_string_is_valid (type_string->str));
646 g_assert (!g_variant_type_string_is_valid (invalid));
649 /* concatenate another type to the type string and ensure that
650 * the result is recognised as being invalid
652 other_type = append_type_string (type_string, description, FALSE, 2);
654 g_string_free (description, TRUE);
655 g_string_free (type_string, TRUE);
656 g_variant_type_free (other_type);
657 g_variant_type_free (type);
661 #define ALIGNED(x, y) (((x + (y - 1)) / y) * y)
663 /* do our own calculation of the fixed_size and alignment of a type
664 * using a simple algorithm to make sure the "fancy" one in the
665 * implementation is correct.
668 calculate_type_info (const GVariantType *type,
672 if (g_variant_type_is_array (type) ||
673 g_variant_type_is_maybe (type))
675 calculate_type_info (g_variant_type_element (type), NULL, alignment);
680 else if (g_variant_type_is_tuple (type) ||
681 g_variant_type_is_dict_entry (type))
683 if (g_variant_type_n_items (type))
685 const GVariantType *sub;
694 sub = g_variant_type_first (type);
700 calculate_type_info (sub, &this_fs, &this_al);
702 al = MAX (al, this_al);
712 size = ALIGNED (size, this_al);
716 while ((sub = g_variant_type_next (sub)));
718 size = ALIGNED (size, al);
739 if (g_variant_type_equal (type, G_VARIANT_TYPE_BOOLEAN) ||
740 g_variant_type_equal (type, G_VARIANT_TYPE_BYTE))
745 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT16) ||
746 g_variant_type_equal (type, G_VARIANT_TYPE_UINT16))
751 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32) ||
752 g_variant_type_equal (type, G_VARIANT_TYPE_UINT32) ||
753 g_variant_type_equal (type, G_VARIANT_TYPE_HANDLE))
758 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT64) ||
759 g_variant_type_equal (type, G_VARIANT_TYPE_UINT64) ||
760 g_variant_type_equal (type, G_VARIANT_TYPE_DOUBLE))
764 else if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING) ||
765 g_variant_type_equal (type, G_VARIANT_TYPE_OBJECT_PATH) ||
766 g_variant_type_equal (type, G_VARIANT_TYPE_SIGNATURE))
771 else if (g_variant_type_equal (type, G_VARIANT_TYPE_VARIANT))
777 g_assert_not_reached ();
787 /* same as the describe_type() function above, but iterates over
788 * typeinfo instead of types.
791 describe_info (GVariantTypeInfo *info)
795 switch (g_variant_type_info_get_type_char (info))
797 case G_VARIANT_TYPE_INFO_CHAR_MAYBE:
801 element = describe_info (g_variant_type_info_element (info));
802 result = g_strdup_printf ("m of %s", element);
807 case G_VARIANT_TYPE_INFO_CHAR_ARRAY:
811 element = describe_info (g_variant_type_info_element (info));
812 result = g_strdup_printf ("a of %s", element);
817 case G_VARIANT_TYPE_INFO_CHAR_TUPLE:
819 const gchar *sep = "";
824 string = g_string_new ("t of [");
825 length = g_variant_type_info_n_members (info);
827 for (i = 0; i < length; i++)
829 const GVariantMemberInfo *minfo;
832 g_string_append (string, sep);
835 minfo = g_variant_type_info_member_info (info, i);
836 subtype = describe_info (minfo->type_info);
837 g_string_append (string, subtype);
841 g_string_append_c (string, ']');
843 result = g_string_free (string, FALSE);
847 case G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY:
849 const GVariantMemberInfo *keyinfo, *valueinfo;
852 g_assert_cmpint (g_variant_type_info_n_members (info), ==, 2);
853 keyinfo = g_variant_type_info_member_info (info, 0);
854 valueinfo = g_variant_type_info_member_info (info, 1);
855 key = describe_info (keyinfo->type_info);
856 value = describe_info (valueinfo->type_info);
857 result = g_strjoin ("", "e of [", key, ", ", value, "]", NULL);
863 case G_VARIANT_TYPE_INFO_CHAR_VARIANT:
864 result = g_strdup ("V");
868 result = g_strdup (g_variant_type_info_get_type_string (info));
869 g_assert_cmpint (strlen (result), ==, 1);
876 /* check that the O(1) method of calculating offsets meshes with the
877 * results of simple iteration.
880 check_offsets (GVariantTypeInfo *info,
881 const GVariantType *type)
886 length = g_variant_type_info_n_members (info);
887 g_assert_cmpint (length, ==, g_variant_type_n_items (type));
889 /* the 'flavour' is the low order bits of the ending point of
890 * variable-size items in the tuple. this lets us test that the type
891 * info is correct for various starting alignments.
893 for (flavour = 0; flavour < 8; flavour++)
895 const GVariantType *subtype;
896 gsize last_offset_index;
901 subtype = g_variant_type_first (type);
902 last_offset_index = -1;
906 /* go through the tuple, keeping track of our position */
907 for (i = 0; i < length; i++)
912 calculate_type_info (subtype, &fixed_size, &alignment);
914 position = ALIGNED (position, alignment);
916 /* compare our current aligned position (ie: the start of this
917 * item) to the start offset that would be calculated if we
921 const GVariantMemberInfo *member;
924 member = g_variant_type_info_member_info (info, i);
925 g_assert_cmpint (member->i, ==, last_offset_index);
927 /* do the calculation using the typeinfo */
933 /* did we reach the same spot? */
934 g_assert_cmpint (start, ==, position);
939 /* fixed size. add that size. */
940 position += fixed_size;
944 /* variable size. do the flavouring. */
945 while ((position & 0x7) != flavour)
948 /* and store the offset, just like it would be in the
951 last_offset = position;
956 subtype = g_variant_type_next (subtype);
959 /* make sure we used up exactly all the types */
960 g_assert (subtype == NULL);
965 test_gvarianttypeinfo (void)
969 for (i = 0; i < 2000; i++)
971 GString *type_string, *description;
972 gsize fixed_size1, fixed_size2;
973 guint alignment1, alignment2;
974 GVariantTypeInfo *info;
978 type_string = g_string_new (NULL);
979 description = g_string_new (NULL);
982 type = append_type_string (type_string, description, TRUE, 6);
984 /* create a typeinfo for it */
985 info = g_variant_type_info_get (type);
987 /* make sure the typeinfo has the right type string */
988 g_assert_cmpstr (g_variant_type_info_get_type_string (info), ==,
991 /* calculate the alignment and fixed size, compare to the
992 * typeinfo's calculations
994 calculate_type_info (type, &fixed_size1, &alignment1);
995 g_variant_type_info_query (info, &alignment2, &fixed_size2);
996 g_assert_cmpint (fixed_size1, ==, fixed_size2);
997 g_assert_cmpint (alignment1, ==, alignment2 + 1);
999 /* test the iteration functions over typeinfo structures by
1000 * "describing" the typeinfo and verifying equality.
1002 desc = describe_info (info);
1003 g_assert_cmpstr (desc, ==, description->str);
1005 /* do extra checks for containers */
1006 if (g_variant_type_is_array (type) ||
1007 g_variant_type_is_maybe (type))
1009 const GVariantType *element;
1013 element = g_variant_type_element (type);
1014 calculate_type_info (element, &efs1, &ea1);
1015 g_variant_type_info_query_element (info, &ea2, &efs2);
1016 g_assert_cmpint (efs1, ==, efs2);
1017 g_assert_cmpint (ea1, ==, ea2 + 1);
1019 g_assert_cmpint (ea1, ==, alignment1);
1020 g_assert_cmpint (0, ==, fixed_size1);
1022 else if (g_variant_type_is_tuple (type) ||
1023 g_variant_type_is_dict_entry (type))
1025 /* make sure the "magic constants" are working */
1026 check_offsets (info, type);
1029 g_string_free (type_string, TRUE);
1030 g_string_free (description, TRUE);
1031 g_variant_type_info_unref (info);
1032 g_variant_type_free (type);
1036 g_variant_type_info_assert_no_infos ();
1039 #define MAX_FIXED_MULTIPLIER 256
1040 #define MAX_INSTANCE_SIZE 1024
1041 #define MAX_ARRAY_CHILDREN 128
1042 #define MAX_TUPLE_CHILDREN 128
1044 /* this function generates a random type such that all characteristics
1045 * that are "interesting" to the serialiser are tested.
1047 * this basically means:
1048 * - test different alignments
1049 * - test variable sized items and fixed sized items
1050 * - test different fixed sizes
1053 random_type_string (void)
1055 const guchar base_types[] = "ynix";
1058 base_type = base_types[g_test_rand_int_range (0, 4)];
1060 if (g_test_rand_bit ())
1061 /* construct a fixed-sized type */
1063 char type_string[MAX_FIXED_MULTIPLIER];
1067 multiplier = g_test_rand_int_range (1, sizeof type_string - 1);
1069 type_string[i++] = '(';
1070 while (multiplier--)
1071 type_string[i++] = base_type;
1072 type_string[i++] = ')';
1074 return g_strndup (type_string, i);
1077 /* construct a variable-sized type */
1079 char type_string[2] = { 'a', base_type };
1081 return g_strndup (type_string, 2);
1087 GVariantTypeInfo *type_info;
1090 gboolean is_fixed_sized;
1094 #define INSTANCE_MAGIC 1287582829
1098 static RandomInstance *
1099 random_instance (GVariantTypeInfo *type_info)
1101 RandomInstance *instance;
1103 instance = g_slice_new (RandomInstance);
1105 if (type_info == NULL)
1107 gchar *str = random_type_string ();
1108 instance->type_info = g_variant_type_info_get (G_VARIANT_TYPE (str));
1112 instance->type_info = g_variant_type_info_ref (type_info);
1114 instance->seed = g_test_rand_int ();
1116 g_variant_type_info_query (instance->type_info,
1117 &instance->alignment,
1120 instance->is_fixed_sized = instance->size != 0;
1122 if (!instance->is_fixed_sized)
1123 instance->size = g_test_rand_int_range (0, MAX_INSTANCE_SIZE);
1125 instance->magic = INSTANCE_MAGIC;
1131 random_instance_free (RandomInstance *instance)
1133 g_variant_type_info_unref (instance->type_info);
1134 g_slice_free (RandomInstance, instance);
1138 append_instance_size (RandomInstance *instance,
1141 *offset += (-*offset) & instance->alignment;
1142 *offset += instance->size;
1146 random_instance_write (RandomInstance *instance,
1152 g_assert_cmpint ((gsize) buffer & ALIGN_BITS & instance->alignment, ==, 0);
1154 rand = g_rand_new_with_seed (instance->seed);
1155 for (i = 0; i < instance->size; i++)
1156 buffer[i] = g_rand_int (rand);
1161 append_instance_data (RandomInstance *instance,
1164 while (((gsize) *buffer) & instance->alignment)
1165 *(*buffer)++ = '\0';
1167 random_instance_write (instance, *buffer);
1168 *buffer += instance->size;
1172 random_instance_assert (RandomInstance *instance,
1179 g_assert_cmpint ((gsize) buffer & ALIGN_BITS & instance->alignment, ==, 0);
1180 g_assert_cmpint (size, ==, instance->size);
1182 rand = g_rand_new_with_seed (instance->seed);
1183 for (i = 0; i < instance->size; i++)
1185 guchar byte = g_rand_int (rand);
1187 g_assert (buffer[i] == byte);
1191 return i == instance->size;
1195 random_instance_check (RandomInstance *instance,
1202 g_assert_cmpint ((gsize) buffer & ALIGN_BITS & instance->alignment, ==, 0);
1204 if (size != instance->size)
1207 rand = g_rand_new_with_seed (instance->seed);
1208 for (i = 0; i < instance->size; i++)
1209 if (buffer[i] != (guchar) g_rand_int (rand))
1213 return i == instance->size;
1217 random_instance_filler (GVariantSerialised *serialised,
1220 RandomInstance *instance = data;
1222 g_assert (instance->magic == INSTANCE_MAGIC);
1224 if (serialised->type_info == NULL)
1225 serialised->type_info = instance->type_info;
1227 if (serialised->size == 0)
1228 serialised->size = instance->size;
1230 g_assert (serialised->type_info == instance->type_info);
1231 g_assert (serialised->size == instance->size);
1233 if (serialised->data)
1234 random_instance_write (instance, serialised->data);
1238 calculate_offset_size (gsize body_size,
1244 if (body_size + n_offsets <= G_MAXUINT8)
1247 if (body_size + 2 * n_offsets <= G_MAXUINT16)
1250 if (body_size + 4 * n_offsets <= G_MAXUINT32)
1253 /* the test case won't generate anything bigger */
1254 g_assert_not_reached ();
1258 flavoured_malloc (gsize size, gsize flavour)
1260 g_assert (flavour < 8);
1265 return ((gchar *) g_malloc (size + flavour)) + flavour;
1269 flavoured_free (gpointer data,
1274 g_free (((gchar *) data) - flavour);
1278 append_offset (guchar **offset_ptr,
1284 guchar bytes[sizeof (gsize)];
1288 tmpvalue.integer = GSIZE_TO_LE (offset);
1289 memcpy (*offset_ptr, tmpvalue.bytes, offset_size);
1290 *offset_ptr += offset_size;
1294 prepend_offset (guchar **offset_ptr,
1300 guchar bytes[sizeof (gsize)];
1304 *offset_ptr -= offset_size;
1305 tmpvalue.integer = GSIZE_TO_LE (offset);
1306 memcpy (*offset_ptr, tmpvalue.bytes, offset_size);
1312 GVariantTypeInfo *type_info;
1313 RandomInstance *instance;
1317 instance = random_instance (NULL);
1320 const gchar *element;
1323 element = g_variant_type_info_get_type_string (instance->type_info);
1324 tmp = g_strdup_printf ("m%s", element);
1325 type_info = g_variant_type_info_get (G_VARIANT_TYPE (tmp));
1329 needed_size = g_variant_serialiser_needed_size (type_info,
1330 random_instance_filler,
1332 g_assert_cmpint (needed_size, ==, 0);
1334 needed_size = g_variant_serialiser_needed_size (type_info,
1335 random_instance_filler,
1336 (gpointer *) &instance, 1);
1338 if (instance->is_fixed_sized)
1339 g_assert_cmpint (needed_size, ==, instance->size);
1341 g_assert_cmpint (needed_size, ==, instance->size + 1);
1346 ptr = data = g_malloc (needed_size);
1347 append_instance_data (instance, &ptr);
1349 if (!instance->is_fixed_sized)
1352 g_assert_cmpint (ptr - data, ==, needed_size);
1359 alignment = (instance->alignment & ALIGN_BITS) + 1;
1361 for (flavour = 0; flavour < 8; flavour += alignment)
1363 GVariantSerialised serialised;
1364 GVariantSerialised child;
1366 serialised.type_info = type_info;
1367 serialised.data = flavoured_malloc (needed_size, flavour);
1368 serialised.size = needed_size;
1370 g_variant_serialiser_serialise (serialised,
1371 random_instance_filler,
1372 (gpointer *) &instance, 1);
1373 child = g_variant_serialised_get_child (serialised, 0);
1374 g_assert (child.type_info == instance->type_info);
1375 random_instance_assert (instance, child.data, child.size);
1376 g_variant_type_info_unref (child.type_info);
1377 flavoured_free (serialised.data, flavour);
1381 g_variant_type_info_unref (type_info);
1382 random_instance_free (instance);
1391 for (i = 0; i < 1000; i++)
1394 g_variant_type_info_assert_no_infos ();
1400 GVariantTypeInfo *element_info;
1401 GVariantTypeInfo *array_info;
1402 RandomInstance **instances;
1409 gchar *element_type, *array_type;
1411 element_type = random_type_string ();
1412 array_type = g_strdup_printf ("a%s", element_type);
1414 element_info = g_variant_type_info_get (G_VARIANT_TYPE (element_type));
1415 array_info = g_variant_type_info_get (G_VARIANT_TYPE (array_type));
1416 g_assert (g_variant_type_info_element (array_info) == element_info);
1418 g_free (element_type);
1419 g_free (array_type);
1425 n_children = g_test_rand_int_range (0, MAX_ARRAY_CHILDREN);
1426 instances = g_new (RandomInstance *, n_children);
1427 for (i = 0; i < n_children; i++)
1428 instances[i] = random_instance (element_info);
1431 needed_size = g_variant_serialiser_needed_size (array_info,
1432 random_instance_filler,
1433 (gpointer *) instances,
1437 gsize element_fixed_size;
1438 gsize body_size = 0;
1441 for (i = 0; i < n_children; i++)
1442 append_instance_size (instances[i], &body_size);
1444 g_variant_type_info_query (element_info, NULL, &element_fixed_size);
1446 if (!element_fixed_size)
1448 offset_size = calculate_offset_size (body_size, n_children);
1450 if (offset_size == 0)
1456 g_assert_cmpint (needed_size, ==, body_size + n_children * offset_size);
1460 guchar *offset_ptr, *body_ptr;
1463 body_ptr = data = g_malloc (needed_size);
1464 offset_ptr = body_ptr + needed_size - offset_size * n_children;
1466 for (i = 0; i < n_children; i++)
1468 append_instance_data (instances[i], &body_ptr);
1469 append_offset (&offset_ptr, body_ptr - data, offset_size);
1472 g_assert (body_ptr == data + needed_size - offset_size * n_children);
1473 g_assert (offset_ptr == data + needed_size);
1481 g_variant_type_info_query (array_info, &alignment, NULL);
1482 alignment = (alignment & ALIGN_BITS) + 1;
1484 for (flavour = 0; flavour < 8; flavour += alignment)
1486 GVariantSerialised serialised;
1488 serialised.type_info = array_info;
1489 serialised.data = flavoured_malloc (needed_size, flavour);
1490 serialised.size = needed_size;
1492 g_variant_serialiser_serialise (serialised, random_instance_filler,
1493 (gpointer *) instances, n_children);
1495 g_assert (memcmp (serialised.data, data, serialised.size) == 0);
1496 g_assert (g_variant_serialised_n_children (serialised) == n_children);
1498 for (i = 0; i < n_children; i++)
1500 GVariantSerialised child;
1502 child = g_variant_serialised_get_child (serialised, i);
1503 g_assert (child.type_info == instances[i]->type_info);
1504 random_instance_assert (instances[i], child.data, child.size);
1505 g_variant_type_info_unref (child.type_info);
1508 flavoured_free (serialised.data, flavour);
1515 for (i = 0; i < n_children; i++)
1516 random_instance_free (instances[i]);
1520 g_variant_type_info_unref (element_info);
1521 g_variant_type_info_unref (array_info);
1530 for (i = 0; i < 100; i++)
1533 g_variant_type_info_assert_no_infos ();
1539 GVariantTypeInfo *type_info;
1540 RandomInstance **instances;
1541 gboolean fixed_size;
1548 n_children = g_test_rand_int_range (0, MAX_TUPLE_CHILDREN);
1549 instances = g_new (RandomInstance *, n_children);
1552 GString *type_string;
1558 type_string = g_string_new ("(");
1559 for (i = 0; i < n_children; i++)
1563 instances[i] = random_instance (NULL);
1565 alignment |= instances[i]->alignment;
1566 if (!instances[i]->is_fixed_sized)
1569 str = g_variant_type_info_get_type_string (instances[i]->type_info);
1570 g_string_append (type_string, str);
1572 g_string_append_c (type_string, ')');
1574 type_info = g_variant_type_info_get (G_VARIANT_TYPE (type_string->str));
1575 g_string_free (type_string, TRUE);
1578 needed_size = g_variant_serialiser_needed_size (type_info,
1579 random_instance_filler,
1580 (gpointer *) instances,
1583 gsize body_size = 0;
1587 for (i = 0; i < n_children; i++)
1589 append_instance_size (instances[i], &body_size);
1591 if (i != n_children - 1 && !instances[i]->is_fixed_sized)
1597 body_size += (-body_size) & alignment;
1599 g_assert ((body_size == 0) == (n_children == 0));
1600 if (n_children == 0)
1604 offset_size = calculate_offset_size (body_size, offsets);
1605 g_assert_cmpint (needed_size, ==, body_size + offsets * offset_size);
1613 body_ptr = data = g_malloc (needed_size);
1614 ofs_ptr = body_ptr + needed_size;
1616 for (i = 0; i < n_children; i++)
1618 append_instance_data (instances[i], &body_ptr);
1620 if (i != n_children - 1 && !instances[i]->is_fixed_sized)
1621 prepend_offset (&ofs_ptr, body_ptr - data, offset_size);
1626 while (((gsize) body_ptr) & alignment)
1629 g_assert ((body_ptr == data) == (n_children == 0));
1630 if (n_children == 0)
1636 g_assert (body_ptr == ofs_ptr);
1643 alignment = (alignment & ALIGN_BITS) + 1;
1645 for (flavour = 0; flavour < 8; flavour += alignment)
1647 GVariantSerialised serialised;
1649 serialised.type_info = type_info;
1650 serialised.data = flavoured_malloc (needed_size, flavour);
1651 serialised.size = needed_size;
1653 g_variant_serialiser_serialise (serialised, random_instance_filler,
1654 (gpointer *) instances, n_children);
1656 g_assert (memcmp (serialised.data, data, serialised.size) == 0);
1657 g_assert (g_variant_serialised_n_children (serialised) == n_children);
1659 for (i = 0; i < n_children; i++)
1661 GVariantSerialised child;
1663 child = g_variant_serialised_get_child (serialised, i);
1664 g_assert (child.type_info == instances[i]->type_info);
1665 random_instance_assert (instances[i], child.data, child.size);
1666 g_variant_type_info_unref (child.type_info);
1669 flavoured_free (serialised.data, flavour);
1676 for (i = 0; i < n_children; i++)
1677 random_instance_free (instances[i]);
1681 g_variant_type_info_unref (type_info);
1690 for (i = 0; i < 100; i++)
1693 g_variant_type_info_assert_no_infos ();
1699 GVariantTypeInfo *type_info;
1700 RandomInstance *instance;
1701 const gchar *type_string;
1706 type_info = g_variant_type_info_get (G_VARIANT_TYPE_VARIANT);
1707 instance = random_instance (NULL);
1709 type_string = g_variant_type_info_get_type_string (instance->type_info);
1710 len = strlen (type_string);
1712 needed_size = g_variant_serialiser_needed_size (type_info,
1713 random_instance_filler,
1714 (gpointer *) &instance, 1);
1716 g_assert_cmpint (needed_size, ==, instance->size + 1 + len);
1721 ptr = data = g_malloc (needed_size);
1722 append_instance_data (instance, &ptr);
1724 memcpy (ptr, type_string, len);
1727 g_assert (data + needed_size == ptr);
1734 /* variants are always 8-aligned */
1735 alignment = ALIGN_BITS + 1;
1737 for (flavour = 0; flavour < 8; flavour += alignment)
1739 GVariantSerialised serialised;
1740 GVariantSerialised child;
1742 serialised.type_info = type_info;
1743 serialised.data = flavoured_malloc (needed_size, flavour);
1744 serialised.size = needed_size;
1746 g_variant_serialiser_serialise (serialised, random_instance_filler,
1747 (gpointer *) &instance, 1);
1749 g_assert (memcmp (serialised.data, data, serialised.size) == 0);
1750 g_assert (g_variant_serialised_n_children (serialised) == 1);
1752 child = g_variant_serialised_get_child (serialised, 0);
1753 g_assert (child.type_info == instance->type_info);
1754 random_instance_check (instance, child.data, child.size);
1756 g_variant_type_info_unref (child.type_info);
1757 flavoured_free (serialised.data, flavour);
1761 g_variant_type_info_unref (type_info);
1762 random_instance_free (instance);
1767 test_variants (void)
1771 for (i = 0; i < 100; i++)
1774 g_variant_type_info_assert_no_infos ();
1787 #define is_objpath is_string | 2
1788 #define is_sig is_string | 4
1790 { is_nval, 0, NULL },
1791 { is_nval, 13, "hello\xffworld!" },
1792 { is_string, 13, "hello world!" },
1793 { is_nval, 13, "hello world\0" },
1794 { is_nval, 13, "hello\0world!" },
1795 { is_nval, 12, "hello world!" },
1797 { is_objpath, 2, "/" },
1798 { is_objpath, 3, "/a" },
1799 { is_string, 3, "//" },
1800 { is_objpath, 11, "/some/path" },
1801 { is_string, 12, "/some/path/" },
1802 { is_nval, 11, "/some\0path" },
1803 { is_string, 11, "/some\\path" },
1804 { is_string, 12, "/some//path" },
1805 { is_string, 12, "/some-/path" },
1809 { is_sig, 5, "(si)" },
1810 { is_string, 4, "(si" },
1811 { is_string, 2, "*" },
1812 { is_sig, 3, "ai" },
1813 { is_string, 3, "mi" },
1814 { is_string, 2, "r" },
1815 { is_sig, 15, "(yyy{sv}ssiai)" },
1816 { is_string, 16, "(yyy{yv}ssiai))" },
1817 { is_string, 15, "(yyy{vv}ssiai)" },
1818 { is_string, 15, "(yyy{sv)ssiai}" }
1822 for (i = 0; i < G_N_ELEMENTS (test_cases); i++)
1826 flags = g_variant_serialiser_is_string (test_cases[i].data,
1830 flags |= g_variant_serialiser_is_object_path (test_cases[i].data,
1834 flags |= g_variant_serialiser_is_signature (test_cases[i].data,
1838 g_assert (flags == test_cases[i].flags);
1842 typedef struct _TreeInstance TreeInstance;
1843 struct _TreeInstance
1845 GVariantTypeInfo *info;
1847 TreeInstance **children;
1858 static GVariantType *
1859 make_random_definite_type (int depth)
1861 GString *description;
1862 GString *type_string;
1865 description = g_string_new (NULL);
1866 type_string = g_string_new (NULL);
1867 type = append_type_string (type_string, description, TRUE, depth);
1868 g_string_free (description, TRUE);
1869 g_string_free (type_string, TRUE);
1875 make_random_string (gchar *string,
1877 const GVariantType *type)
1881 /* create strings that are valid signature strings */
1882 #define good_chars "bynqiuxthdsog"
1884 for (i = 0; i < size - 1; i++)
1885 string[i] = good_chars[g_test_rand_int_range (0, strlen (good_chars))];
1888 /* in case we need an object path, prefix a '/' */
1889 if (*g_variant_type_peek_string (type) == 'o')
1895 static TreeInstance *
1896 tree_instance_new (const GVariantType *type,
1899 const GVariantType *child_type = NULL;
1900 GVariantType *mytype = NULL;
1901 TreeInstance *instance;
1902 gboolean is_tuple_type;
1905 type = mytype = make_random_definite_type (depth);
1907 instance = g_slice_new (TreeInstance);
1908 instance->info = g_variant_type_info_get (type);
1909 instance->children = NULL;
1910 instance->n_children = 0;
1911 instance->data_size = 0;
1913 is_tuple_type = FALSE;
1915 switch (*g_variant_type_peek_string (type))
1917 case G_VARIANT_TYPE_INFO_CHAR_MAYBE:
1918 instance->n_children = g_test_rand_int_range (0, 2);
1919 child_type = g_variant_type_element (type);
1922 case G_VARIANT_TYPE_INFO_CHAR_ARRAY:
1923 instance->n_children = g_test_rand_int_range (0, MAX_ARRAY_CHILDREN);
1924 child_type = g_variant_type_element (type);
1927 case G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY:
1928 case G_VARIANT_TYPE_INFO_CHAR_TUPLE:
1929 instance->n_children = g_variant_type_n_items (type);
1930 child_type = g_variant_type_first (type);
1931 is_tuple_type = TRUE;
1934 case G_VARIANT_TYPE_INFO_CHAR_VARIANT:
1935 instance->n_children = 1;
1940 instance->data.integer = g_test_rand_int_range (0, 2);
1941 instance->data_size = 1;
1945 instance->data.integer = g_test_rand_int ();
1946 instance->data_size = 1;
1950 instance->data.integer = g_test_rand_int ();
1951 instance->data_size = 2;
1954 case 'i': case 'u': case 'h':
1955 instance->data.integer = g_test_rand_int ();
1956 instance->data_size = 4;
1960 instance->data.integer = g_test_rand_int ();
1961 instance->data.integer <<= 32;
1962 instance->data.integer |= (guint32) g_test_rand_int ();
1963 instance->data_size = 8;
1967 instance->data.floating = g_test_rand_double ();
1968 instance->data_size = 8;
1971 case 's': case 'o': case 'g':
1972 instance->data_size = g_test_rand_int_range (10, 20);
1973 make_random_string (instance->data.string, instance->data_size, type);
1977 if (instance->data_size == 0)
1978 /* no data -> it is a container */
1982 instance->children = g_new (TreeInstance *, instance->n_children);
1984 for (i = 0; i < instance->n_children; i++)
1986 instance->children[i] = tree_instance_new (child_type, depth - 1);
1989 child_type = g_variant_type_next (child_type);
1992 g_assert (!is_tuple_type || child_type == NULL);
1995 g_variant_type_free (mytype);
2001 tree_instance_free (TreeInstance *instance)
2005 g_variant_type_info_unref (instance->info);
2006 for (i = 0; i < instance->n_children; i++)
2007 tree_instance_free (instance->children[i]);
2008 g_free (instance->children);
2009 g_slice_free (TreeInstance, instance);
2012 static gboolean i_am_writing_byteswapped;
2015 tree_filler (GVariantSerialised *serialised,
2018 TreeInstance *instance = data;
2020 if (serialised->type_info == NULL)
2021 serialised->type_info = instance->info;
2023 if (instance->data_size == 0)
2024 /* is a container */
2026 if (serialised->size == 0)
2028 g_variant_serialiser_needed_size (instance->info, tree_filler,
2029 (gpointer *) instance->children,
2030 instance->n_children);
2032 if (serialised->data)
2033 g_variant_serialiser_serialise (*serialised, tree_filler,
2034 (gpointer *) instance->children,
2035 instance->n_children);
2040 if (serialised->size == 0)
2041 serialised->size = instance->data_size;
2043 if (serialised->data)
2045 switch (instance->data_size)
2048 *serialised->data = instance->data.integer;
2053 guint16 value = instance->data.integer;
2055 if (i_am_writing_byteswapped)
2056 value = GUINT16_SWAP_LE_BE (value);
2058 *(guint16 *) serialised->data = value;
2064 guint32 value = instance->data.integer;
2066 if (i_am_writing_byteswapped)
2067 value = GUINT32_SWAP_LE_BE (value);
2069 *(guint32 *) serialised->data = value;
2075 guint64 value = instance->data.integer;
2077 if (i_am_writing_byteswapped)
2078 value = GUINT64_SWAP_LE_BE (value);
2080 *(guint64 *) serialised->data = value;
2085 memcpy (serialised->data,
2086 instance->data.string,
2087 instance->data_size);
2095 check_tree (TreeInstance *instance,
2096 GVariantSerialised serialised)
2098 if (instance->info != serialised.type_info)
2101 if (instance->data_size == 0)
2102 /* is a container */
2106 if (g_variant_serialised_n_children (serialised) !=
2107 instance->n_children)
2110 for (i = 0; i < instance->n_children; i++)
2112 GVariantSerialised child;
2113 gpointer data = NULL;
2116 child = g_variant_serialised_get_child (serialised, i);
2117 if (child.size && child.data == NULL)
2118 child.data = data = g_malloc0 (child.size);
2119 ok = check_tree (instance->children[i], child);
2120 g_variant_type_info_unref (child.type_info);
2132 switch (instance->data_size)
2135 g_assert (serialised.size == 1);
2136 return *(guint8 *) serialised.data ==
2137 (guint8) instance->data.integer;
2140 g_assert (serialised.size == 2);
2141 return *(guint16 *) serialised.data ==
2142 (guint16) instance->data.integer;
2145 g_assert (serialised.size == 4);
2146 return *(guint32 *) serialised.data ==
2147 (guint32) instance->data.integer;
2150 g_assert (serialised.size == 8);
2151 return *(guint64 *) serialised.data ==
2152 (guint64) instance->data.integer;
2155 if (serialised.size != instance->data_size)
2158 return memcmp (serialised.data,
2159 instance->data.string,
2160 instance->data_size) == 0;
2166 serialise_tree (TreeInstance *tree,
2167 GVariantSerialised *serialised)
2169 GVariantSerialised empty = { };
2171 *serialised = empty;
2172 tree_filler (serialised, tree);
2173 serialised->data = g_malloc (serialised->size);
2174 tree_filler (serialised, tree);
2178 test_byteswap (void)
2180 GVariantSerialised one, two;
2183 tree = tree_instance_new (NULL, 3);
2184 serialise_tree (tree, &one);
2186 i_am_writing_byteswapped = TRUE;
2187 serialise_tree (tree, &two);
2188 i_am_writing_byteswapped = FALSE;
2190 g_variant_serialised_byteswap (two);
2192 g_assert_cmpint (one.size, ==, two.size);
2193 g_assert (memcmp (one.data, two.data, one.size) == 0);
2195 tree_instance_free (tree);
2201 test_byteswaps (void)
2205 for (i = 0; i < 200; i++)
2208 g_variant_type_info_assert_no_infos ();
2212 test_fuzz (gdouble *fuzziness)
2214 GVariantSerialised serialised;
2217 /* make an instance */
2218 tree = tree_instance_new (NULL, 3);
2221 serialise_tree (tree, &serialised);
2223 g_assert (g_variant_serialised_is_normal (serialised));
2224 g_assert (check_tree (tree, serialised));
2226 if (serialised.size)
2228 gboolean fuzzed = FALSE;
2235 for (i = 0; i < serialised.size; i++)
2236 if (randomly (*fuzziness))
2238 serialised.data[i] += g_test_rand_int_range (1, 256);
2243 /* at least one byte in the serialised data has changed.
2245 * this means that at least one of the following is true:
2247 * - the serialised data now represents a different value:
2248 * check_tree() will return FALSE
2250 * - the serialised data is in non-normal form:
2251 * g_variant_serialiser_is_normal() will return FALSE
2253 * we always do both checks to increase exposure of the serialiser
2256 a = g_variant_serialised_is_normal (serialised);
2257 b = check_tree (tree, serialised);
2259 g_assert (!a || !b);
2262 tree_instance_free (tree);
2263 g_free (serialised.data);
2268 test_fuzzes (gpointer data)
2273 fuzziness = GPOINTER_TO_INT (data) / 100.;
2275 for (i = 0; i < 200; i++)
2276 test_fuzz (&fuzziness);
2278 g_variant_type_info_assert_no_infos ();
2282 tree_instance_get_gvariant (TreeInstance *tree)
2284 const GVariantType *type;
2287 type = (GVariantType *) g_variant_type_info_get_type_string (tree->info);
2289 switch (g_variant_type_info_get_type_char (tree->info))
2291 case G_VARIANT_TYPE_INFO_CHAR_MAYBE:
2293 const GVariantType *child_type;
2296 if (tree->n_children)
2297 child = tree_instance_get_gvariant (tree->children[0]);
2301 child_type = g_variant_type_element (type);
2303 if (child != NULL && randomly (0.5))
2306 result = g_variant_new_maybe (child_type, child);
2310 case G_VARIANT_TYPE_INFO_CHAR_ARRAY:
2312 const GVariantType *child_type;
2313 GVariant **children;
2316 children = g_new (GVariant *, tree->n_children);
2317 for (i = 0; i < tree->n_children; i++)
2318 children[i] = tree_instance_get_gvariant (tree->children[i]);
2320 child_type = g_variant_type_element (type);
2322 if (i > 0 && randomly (0.5))
2325 result = g_variant_new_array (child_type, children, tree->n_children);
2330 case G_VARIANT_TYPE_INFO_CHAR_TUPLE:
2332 GVariant **children;
2335 children = g_new (GVariant *, tree->n_children);
2336 for (i = 0; i < tree->n_children; i++)
2337 children[i] = tree_instance_get_gvariant (tree->children[i]);
2339 result = g_variant_new_tuple (children, tree->n_children);
2344 case G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY:
2346 GVariant *key, *val;
2348 g_assert (tree->n_children == 2);
2350 key = tree_instance_get_gvariant (tree->children[0]);
2351 val = tree_instance_get_gvariant (tree->children[1]);
2353 result = g_variant_new_dict_entry (key, val);
2357 case G_VARIANT_TYPE_INFO_CHAR_VARIANT:
2361 g_assert (tree->n_children == 1);
2363 value = tree_instance_get_gvariant (tree->children[0]);
2364 result = g_variant_new_variant (value);
2369 result = g_variant_new_boolean (tree->data.integer > 0);
2373 result = g_variant_new_byte (tree->data.integer);
2377 result = g_variant_new_int16 (tree->data.integer);
2381 result = g_variant_new_uint16 (tree->data.integer);
2385 result = g_variant_new_int32 (tree->data.integer);
2389 result = g_variant_new_uint32 (tree->data.integer);
2393 result = g_variant_new_int64 (tree->data.integer);
2397 result = g_variant_new_uint64 (tree->data.integer);
2401 result = g_variant_new_handle (tree->data.integer);
2405 result = g_variant_new_double (tree->data.floating);
2409 result = g_variant_new_string (tree->data.string);
2413 result = g_variant_new_object_path (tree->data.string);
2417 result = g_variant_new_signature (tree->data.string);
2421 g_assert_not_reached ();
2428 tree_instance_check_gvariant (TreeInstance *tree,
2431 const GVariantType *type;
2433 type = (GVariantType *) g_variant_type_info_get_type_string (tree->info);
2434 g_assert (g_variant_is_of_type (value, type));
2436 switch (g_variant_type_info_get_type_char (tree->info))
2438 case G_VARIANT_TYPE_INFO_CHAR_MAYBE:
2443 child = g_variant_get_maybe (value);
2445 if (child != NULL && tree->n_children == 1)
2446 equal = tree_instance_check_gvariant (tree->children[0], child);
2447 else if (child == NULL && tree->n_children == 0)
2453 g_variant_unref (child);
2459 case G_VARIANT_TYPE_INFO_CHAR_ARRAY:
2460 case G_VARIANT_TYPE_INFO_CHAR_TUPLE:
2461 case G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY:
2465 if (g_variant_n_children (value) != tree->n_children)
2468 for (i = 0; i < tree->n_children; i++)
2473 child = g_variant_get_child_value (value, i);
2474 equal = tree_instance_check_gvariant (tree->children[i], child);
2475 g_variant_unref (child);
2485 case G_VARIANT_TYPE_INFO_CHAR_VARIANT:
2487 const gchar *str1, *str2;
2491 child = g_variant_get_variant (value);
2492 str1 = g_variant_get_type_string (child);
2493 str2 = g_variant_type_info_get_type_string (tree->children[0]->info);
2494 /* GVariant only keeps one copy of type strings around */
2495 equal = str1 == str2 &&
2496 tree_instance_check_gvariant (tree->children[0], child);
2498 g_variant_unref (child);
2505 return g_variant_get_boolean (value) == tree->data.integer;
2508 return g_variant_get_byte (value) == (guchar) tree->data.integer;
2511 return g_variant_get_int16 (value) == (gint16) tree->data.integer;
2514 return g_variant_get_uint16 (value) == (guint16) tree->data.integer;
2517 return g_variant_get_int32 (value) == (gint32) tree->data.integer;
2520 return g_variant_get_uint32 (value) == (guint32) tree->data.integer;
2523 return g_variant_get_int64 (value) == (gint64) tree->data.integer;
2526 return g_variant_get_uint64 (value) == (guint64) tree->data.integer;
2529 return g_variant_get_handle (value) == (gint32) tree->data.integer;
2533 gdouble floating = g_variant_get_double (value);
2535 return memcmp (&floating, &tree->data.floating, sizeof floating) == 0;
2541 return strcmp (g_variant_get_string (value, NULL),
2542 tree->data.string) == 0;
2545 g_assert_not_reached ();
2550 tree_instance_build_gvariant (TreeInstance *tree,
2551 GVariantBuilder *builder,
2554 const GVariantType *type;
2556 type = (GVariantType *) g_variant_type_info_get_type_string (tree->info);
2558 if (g_variant_type_is_container (type))
2562 /* force GVariantBuilder to guess the type half the time */
2563 if (guess_ok && randomly (0.5))
2565 if (g_variant_type_is_array (type) && tree->n_children)
2566 type = G_VARIANT_TYPE_ARRAY;
2568 if (g_variant_type_is_maybe (type) && tree->n_children)
2569 type = G_VARIANT_TYPE_MAYBE;
2571 if (g_variant_type_is_tuple (type))
2572 type = G_VARIANT_TYPE_TUPLE;
2574 if (g_variant_type_is_dict_entry (type))
2575 type = G_VARIANT_TYPE_DICT_ENTRY;
2580 g_variant_builder_open (builder, type);
2582 for (i = 0; i < tree->n_children; i++)
2583 tree_instance_build_gvariant (tree->children[i], builder, guess_ok);
2585 g_variant_builder_close (builder);
2588 g_variant_builder_add_value (builder, tree_instance_get_gvariant (tree));
2593 tree_instance_check_iter (TreeInstance *tree,
2598 value = g_variant_iter_next_value (iter);
2600 if (g_variant_is_container (value))
2604 iter = g_variant_iter_new (value);
2605 g_variant_unref (value);
2607 if (g_variant_iter_n_children (iter) != tree->n_children)
2609 g_variant_iter_free (iter);
2613 for (i = 0; i < tree->n_children; i++)
2614 if (!tree_instance_check_iter (tree->children[i], iter))
2616 g_variant_iter_free (iter);
2620 g_assert (g_variant_iter_next_value (iter) == NULL);
2621 g_variant_iter_free (iter);
2630 equal = tree_instance_check_gvariant (tree, value);
2631 g_variant_unref (value);
2638 test_container (void)
2644 tree = tree_instance_new (NULL, 3);
2645 value = g_variant_ref_sink (tree_instance_get_gvariant (tree));
2647 s1 = g_variant_print (value, TRUE);
2648 g_assert (tree_instance_check_gvariant (tree, value));
2650 g_variant_get_data (value);
2652 s2 = g_variant_print (value, TRUE);
2653 g_assert (tree_instance_check_gvariant (tree, value));
2655 g_assert_cmpstr (s1, ==, s2);
2657 if (g_variant_is_container (value))
2659 GVariantBuilder builder;
2665 g_variant_builder_init (&builder, G_VARIANT_TYPE_VARIANT);
2666 tree_instance_build_gvariant (tree, &builder, TRUE);
2667 built = g_variant_builder_end (&builder);
2668 g_variant_ref_sink (built);
2669 g_variant_get_data (built);
2670 val = g_variant_get_variant (built);
2672 s3 = g_variant_print (val, TRUE);
2673 g_assert_cmpstr (s1, ==, s3);
2675 g_variant_iter_init (&iter, built);
2676 g_assert (tree_instance_check_iter (tree, &iter));
2677 g_assert (g_variant_iter_next_value (&iter) == NULL);
2679 g_variant_unref (built);
2680 g_variant_unref (val);
2684 tree_instance_free (tree);
2685 g_variant_unref (value);
2693 const gchar invalid[] = "hello\xffworld";
2696 /* ensure that the test data is not valid utf8... */
2697 g_assert (!g_utf8_validate (invalid, -1, NULL));
2699 /* load the data untrusted */
2700 value = g_variant_new_from_data (G_VARIANT_TYPE_STRING,
2701 invalid, sizeof invalid,
2704 /* ensure that the problem is caught and we get valid UTF-8 */
2705 g_assert (g_utf8_validate (g_variant_get_string (value, NULL), -1, NULL));
2706 g_variant_unref (value);
2709 /* now load it trusted */
2710 value = g_variant_new_from_data (G_VARIANT_TYPE_STRING,
2711 invalid, sizeof invalid,
2714 /* ensure we get the invalid data (ie: make sure that time wasn't
2715 * wasted on validating data that was marked as trusted)
2717 g_assert (g_variant_get_string (value, NULL) == invalid);
2718 g_variant_unref (value);
2722 test_containers (void)
2726 for (i = 0; i < 100; i++)
2731 g_variant_type_info_assert_no_infos ();
2735 test_format_strings (void)
2740 g_assert (g_variant_format_string_scan ("i", NULL, &end) && *end == '\0');
2741 g_assert (g_variant_format_string_scan ("@i", NULL, &end) && *end == '\0');
2742 g_assert (g_variant_format_string_scan ("@ii", NULL, &end) && *end == 'i');
2743 g_assert (g_variant_format_string_scan ("^a&s", NULL, &end) && *end == '\0');
2744 g_assert (g_variant_format_string_scan ("(^as)", NULL, &end) &&
2746 g_assert (!g_variant_format_string_scan ("(^s)", NULL, &end));
2747 g_assert (!g_variant_format_string_scan ("(^a)", NULL, &end));
2748 g_assert (!g_variant_format_string_scan ("(z)", NULL, &end));
2749 g_assert (!g_variant_format_string_scan ("az", NULL, &end));
2750 g_assert (!g_variant_format_string_scan ("{**}", NULL, &end));
2751 g_assert (!g_variant_format_string_scan ("{@**}", NULL, &end));
2752 g_assert (g_variant_format_string_scan ("{@y*}", NULL, &end) &&
2754 g_assert (g_variant_format_string_scan ("{yv}", NULL, &end) &&
2756 g_assert (!g_variant_format_string_scan ("{&?v}", NULL, &end));
2757 g_assert (g_variant_format_string_scan ("{@?v}", NULL, &end) &&
2759 g_assert (!g_variant_format_string_scan ("{&@sv}", NULL, &end));
2760 g_assert (!g_variant_format_string_scan ("{@&sv}", NULL, &end));
2761 g_assert (g_variant_format_string_scan ("{&sv}", NULL, &end) &&
2763 g_assert (!g_variant_format_string_scan ("{vv}", NULL, &end));
2764 g_assert (!g_variant_format_string_scan ("{y}", NULL, &end));
2765 g_assert (!g_variant_format_string_scan ("{yyy}", NULL, &end));
2766 g_assert (!g_variant_format_string_scan ("{ya}", NULL, &end));
2767 g_assert (g_variant_format_string_scan ("&s", NULL, &end) && *end == '\0');
2768 g_assert (!g_variant_format_string_scan ("&as", NULL, &end));
2769 g_assert (!g_variant_format_string_scan ("@z", NULL, &end));
2770 g_assert (!g_variant_format_string_scan ("az", NULL, &end));
2771 g_assert (!g_variant_format_string_scan ("a&s", NULL, &end));
2773 type = g_variant_format_string_scan_type ("mm(@xy^a&s*?@?)", NULL, &end);
2774 g_assert (type && *end == '\0');
2775 g_assert (g_variant_type_equal (type, G_VARIANT_TYPE ("mm(xyas*?\?)")));
2776 g_variant_type_free (type);
2778 type = g_variant_format_string_scan_type ("mm(@xy^a&*?@?)", NULL, NULL);
2779 g_assert (type == NULL);
2783 exit_on_abort (int signal)
2789 do_failed_test (const gchar *pattern)
2791 if (g_test_trap_fork (1000000, G_TEST_TRAP_SILENCE_STDERR))
2793 signal (SIGABRT, exit_on_abort);
2797 g_test_trap_assert_failed ();
2798 g_test_trap_assert_stderr (pattern);
2804 test_invalid_varargs (void)
2806 if (do_failed_test ("*GVariant format string*"))
2808 g_variant_new ("z");
2812 if (do_failed_test ("*valid GVariant format string as a prefix*"))
2816 g_variant_new_va ("z", &end, NULL);
2820 if (do_failed_test ("*type of `q' but * has a type of `y'*"))
2822 g_variant_get (g_variant_new ("y", 'a'), "q");
2828 check_and_free (GVariant *value,
2831 gchar *valstr = g_variant_print (value, FALSE);
2832 g_assert_cmpstr (str, ==, valstr);
2833 g_variant_unref (value);
2841 GVariantBuilder array;
2843 g_variant_builder_init (&array, G_VARIANT_TYPE_ARRAY);
2844 g_variant_builder_add (&array, "{sv}", "size",
2845 g_variant_new ("(ii)", 800, 600));
2846 g_variant_builder_add (&array, "{sv}", "title",
2847 g_variant_new_string ("Test case"));
2848 g_variant_builder_add_value (&array,
2849 g_variant_new_dict_entry (g_variant_new_string ("temperature"),
2850 g_variant_new_variant (
2851 g_variant_new_double (37.5))));
2852 check_and_free (g_variant_new ("(ma{sv}m(a{sv})ma{sv}ii)",
2853 NULL, FALSE, NULL, &array, 7777, 8888),
2854 "(nothing, nothing, {'size': <(800, 600)>, "
2855 "'title': <'Test case'>, "
2856 "'temperature': <37.5>}, "
2859 check_and_free (g_variant_new ("(imimimmimmimmi)",
2866 "(123, nothing, 123, nothing, just nothing, 123)");
2868 check_and_free (g_variant_new ("(ybnixd)",
2869 'a', 1, 22, 33, (guint64) 44, 5.5),
2870 "(0x61, true, 22, 33, 44, 5.5)");
2872 check_and_free (g_variant_new ("(@y?*rv)",
2873 g_variant_new ("y", 'a'),
2874 g_variant_new ("y", 'b'),
2875 g_variant_new ("y", 'c'),
2876 g_variant_new ("(y)", 'd'),
2877 g_variant_new ("y", 'e')),
2878 "(0x61, 0x62, 0x63, (0x64,), <byte 0x65>)");
2882 GVariantBuilder array;
2889 g_variant_builder_init (&array, G_VARIANT_TYPE_ARRAY);
2890 for (i = 0; i < 100; i++)
2892 number = g_strdup_printf ("%d", i);
2893 g_variant_builder_add (&array, "s", number);
2897 value = g_variant_builder_end (&array);
2898 g_variant_iter_init (&iter, value);
2901 while (g_variant_iter_loop (&iter, "s", &number))
2903 gchar *check = g_strdup_printf ("%d", i++);
2904 g_assert_cmpstr (number, ==, check);
2907 g_assert (number == NULL);
2908 g_assert (i == 100);
2910 g_variant_unref (value);
2912 g_variant_builder_init (&array, G_VARIANT_TYPE_ARRAY);
2913 for (i = 0; i < 100; i++)
2914 g_variant_builder_add (&array, "mi", i % 2 == 0, i);
2915 value = g_variant_builder_end (&array);
2918 g_variant_iter_init (&iter, value);
2919 while (g_variant_iter_loop (&iter, "mi", NULL, &val))
2920 g_assert (val == i++ || val == 0);
2921 g_assert (i == 100);
2924 g_variant_iter_init (&iter, value);
2925 while (g_variant_iter_loop (&iter, "mi", &just, &val))
2932 g_assert (val == this);
2937 g_assert (val == 0);
2940 g_assert (i == 100);
2942 g_variant_unref (value);
2946 const gchar *strvector[] = {"/hello", "/world", NULL};
2947 const gchar *test_strs[] = {"/foo", "/bar", "/baz" };
2948 GVariantBuilder builder;
2949 GVariantIter *array;
2957 g_variant_builder_init (&builder, G_VARIANT_TYPE ("ao"));
2958 g_variant_builder_add (&builder, "o", "/foo");
2959 g_variant_builder_add (&builder, "o", "/bar");
2960 g_variant_builder_add (&builder, "o", "/baz");
2961 value = g_variant_new("(ao^ao^a&o)", &builder, strvector, strvector);
2962 g_variant_iter_init (&tuple, value);
2963 g_variant_iter_next (&tuple, "ao", &array);
2966 while (g_variant_iter_loop (array, "o", &str))
2967 g_assert_cmpstr (str, ==, test_strs[i++]);
2970 g_variant_iter_free (array);
2973 g_variant_iter_init (&tuple, value);
2974 g_variant_iter_next (&tuple, "ao", &array);
2977 while (g_variant_iter_loop (array, "&o", &str))
2978 g_assert_cmpstr (str, ==, test_strs[i++]);
2981 g_variant_iter_free (array);
2983 g_variant_iter_next (&tuple, "^a&o", &strv);
2984 g_variant_iter_next (&tuple, "^ao", &my_strv);
2986 g_assert_cmpstr (strv[0], ==, "/hello");
2987 g_assert_cmpstr (strv[1], ==, "/world");
2988 g_assert (strv[2] == NULL);
2989 g_assert_cmpstr (my_strv[0], ==, "/hello");
2990 g_assert_cmpstr (my_strv[1], ==, "/world");
2991 g_assert (my_strv[2] == NULL);
2993 g_variant_unref (value);
2994 g_strfreev (my_strv);
2999 const gchar *strvector[] = { "i", "ii", "iii", "iv", "v", "vi", NULL };
3000 GVariantBuilder builder;
3009 g_variant_builder_init (&builder, G_VARIANT_TYPE ("aag"));
3010 g_variant_builder_open (&builder, G_VARIANT_TYPE ("ag"));
3011 for (i = 0; i < 6; i++)
3013 g_variant_builder_add (&builder, "g", strvector[i]);
3015 g_variant_builder_add (&builder, "&g", strvector[i]);
3016 g_variant_builder_close (&builder);
3017 g_variant_builder_add (&builder, "^ag", strvector);
3018 g_variant_builder_add (&builder, "^ag", strvector);
3019 value = g_variant_new ("aag", &builder);
3021 g_variant_iter_init (&iter, value);
3022 while (g_variant_iter_loop (&iter, "^ag", &strv))
3023 for (i = 0; i < 6; i++)
3024 g_assert_cmpstr (strv[i], ==, strvector[i]);
3026 g_variant_iter_init (&iter, value);
3027 while (g_variant_iter_loop (&iter, "^a&g", &strv))
3028 for (i = 0; i < 6; i++)
3029 g_assert_cmpstr (strv[i], ==, strvector[i]);
3031 g_variant_iter_init (&iter, value);
3032 while (g_variant_iter_loop (&iter, "ag", &i2))
3037 while (g_variant_iter_loop (i2, "g", &str))
3038 g_assert_cmpstr (str, ==, strvector[i++]);
3042 g_variant_iter_init (&iter, value);
3043 i3 = g_variant_iter_copy (&iter);
3044 while (g_variant_iter_loop (&iter, "@ag", &sub))
3046 gchar *str = g_variant_print (sub, TRUE);
3047 g_assert_cmpstr (str, ==,
3048 "[signature 'i', 'ii', 'iii', 'iv', 'v', 'vi']");
3052 if (do_failed_test ("*NULL has already been returned*"))
3054 g_variant_iter_next_value (&iter);
3059 while (g_variant_iter_loop (i3, "*", &sub))
3061 gchar *str = g_variant_print (sub, TRUE);
3062 g_assert_cmpstr (str, ==,
3063 "[signature 'i', 'ii', 'iii', 'iv', 'v', 'vi']");
3067 g_variant_iter_free (i3);
3069 for (i = 0; i < g_variant_n_children (value); i++)
3073 g_variant_get_child (value, i, "*", &sub);
3075 for (j = 0; j < g_variant_n_children (sub); j++)
3077 const gchar *str = NULL;
3080 g_variant_get_child (sub, j, "&g", &str);
3081 g_assert_cmpstr (str, ==, strvector[j]);
3083 cval = g_variant_get_child_value (sub, j);
3084 g_variant_get (cval, "&g", &str);
3085 g_assert_cmpstr (str, ==, strvector[j]);
3086 g_variant_unref (cval);
3089 g_variant_unref (sub);
3092 g_variant_unref (value);
3111 /* test all 'nothing' */
3112 value = g_variant_new ("(mymbmnmqmimumxmtmhmdmv)",
3115 FALSE, (gint16) 123,
3116 FALSE, (guint16) 123,
3117 FALSE, (gint32) 123,
3118 FALSE, (guint32) 123,
3119 FALSE, (gint64) 123,
3120 FALSE, (guint64) 123,
3122 FALSE, (gdouble) 37.5,
3126 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3140 memset (justs, 1, sizeof justs);
3141 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3153 g_assert (!(justs[0] || justs[1] || justs[2] || justs[3] || justs[4] ||
3154 justs[5] || justs[6] || justs[7] || justs[8] || justs[9]));
3157 memset (justs, 1, sizeof justs);
3158 byteval = i16val = u16val = i32val = u32val = i64val = u64val = hval = 88;
3162 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3163 &justs[0], &byteval,
3174 g_assert (!(justs[0] || justs[1] || justs[2] || justs[3] || justs[4] ||
3175 justs[5] || justs[6] || justs[7] || justs[8] || justs[9]));
3176 g_assert (byteval == '\0' && bval == FALSE);
3177 g_assert (i16val == 0 && u16val == 0 && i32val == 0 &&
3178 u32val == 0 && i64val == 0 && u64val == 0 &&
3179 hval == 0 && dval == 0.0);
3180 g_assert (vval == NULL);
3183 byteval = i16val = u16val = i32val = u32val = i64val = u64val = hval = 88;
3187 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3199 g_assert (byteval == '\0' && bval == FALSE);
3200 g_assert (i16val == 0 && u16val == 0 && i32val == 0 &&
3201 u32val == 0 && i64val == 0 && u64val == 0 &&
3202 hval == 0 && dval == 0.0);
3203 g_assert (vval == NULL);
3205 g_variant_unref (value);
3208 /* test all 'just' */
3209 value = g_variant_new ("(mymbmnmqmimumxmtmhmdmv)",
3213 TRUE, (guint16) 123,
3215 TRUE, (guint32) 123,
3217 TRUE, (guint64) 123,
3219 TRUE, (gdouble) 37.5,
3220 g_variant_new ("()"));
3223 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3237 memset (justs, 0, sizeof justs);
3238 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3250 g_assert (justs[0] && justs[1] && justs[2] && justs[3] && justs[4] &&
3251 justs[5] && justs[6] && justs[7] && justs[8] && justs[9]);
3254 memset (justs, 0, sizeof justs);
3255 byteval = i16val = u16val = i32val = u32val = i64val = u64val = hval = 88;
3259 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3260 &justs[0], &byteval,
3271 g_assert (justs[0] && justs[1] && justs[2] && justs[3] && justs[4] &&
3272 justs[5] && justs[6] && justs[7] && justs[8] && justs[9]);
3273 g_assert (byteval == 'a' && bval == TRUE);
3274 g_assert (i16val == 123 && u16val == 123 && i32val == 123 &&
3275 u32val == 123 && i64val == 123 && u64val == 123 &&
3276 hval == -1 && dval == 37.5);
3277 g_assert (g_variant_is_of_type (vval, G_VARIANT_TYPE_UNIT));
3278 g_variant_unref (vval);
3281 byteval = i16val = u16val = i32val = u32val = i64val = u64val = hval = 88;
3285 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3297 g_assert (byteval == 'a' && bval == TRUE);
3298 g_assert (i16val == 123 && u16val == 123 && i32val == 123 &&
3299 u32val == 123 && i64val == 123 && u64val == 123 &&
3300 hval == -1 && dval == 37.5);
3301 g_assert (g_variant_is_of_type (vval, G_VARIANT_TYPE_UNIT));
3302 g_variant_unref (vval);
3304 g_variant_unref (value);
3307 g_variant_type_info_assert_no_infos ();
3311 hash_get (GVariant *value,
3312 const gchar *format,
3315 const gchar *endptr = NULL;
3319 hash = g_str_has_suffix (format, "#");
3321 va_start (ap, format);
3322 g_variant_get_va (value, format, hash ? &endptr : NULL, &ap);
3326 g_assert (*endptr == '#');
3330 hash_new (const gchar *format,
3333 const gchar *endptr = NULL;
3338 hash = g_str_has_suffix (format, "#");
3340 va_start (ap, format);
3341 value = g_variant_new_va (format, hash ? &endptr : NULL, &ap);
3345 g_assert (*endptr == '#');
3357 value = hash_new ("i", 234);
3358 hash_get (value, "i", &x);
3359 g_assert (x == 234);
3360 g_variant_unref (value);
3363 value = hash_new ("i#", 234);
3364 hash_get (value, "i#", &x);
3365 g_assert (x == 234);
3366 g_variant_unref (value);
3368 g_variant_type_info_assert_no_infos ();
3372 test_builder_memory (void)
3374 GVariantBuilder *hb;
3377 hb = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
3378 g_variant_builder_open (hb, G_VARIANT_TYPE_ARRAY);
3379 g_variant_builder_open (hb, G_VARIANT_TYPE_ARRAY);
3380 g_variant_builder_open (hb, G_VARIANT_TYPE_ARRAY);
3381 g_variant_builder_add (hb, "s", "some value");
3382 g_variant_builder_ref (hb);
3383 g_variant_builder_unref (hb);
3384 g_variant_builder_unref (hb);
3386 hb = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
3387 g_variant_builder_unref (hb);
3389 hb = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
3390 g_variant_builder_clear (hb);
3391 g_variant_builder_unref (hb);
3393 g_variant_builder_init (&sb, G_VARIANT_TYPE_ARRAY);
3394 g_variant_builder_open (&sb, G_VARIANT_TYPE_ARRAY);
3395 g_variant_builder_open (&sb, G_VARIANT_TYPE_ARRAY);
3396 g_variant_builder_add (&sb, "s", "some value");
3397 g_variant_builder_clear (&sb);
3399 g_variant_type_info_assert_no_infos ();
3405 GVariant *items[4096];
3409 table = g_hash_table_new_full (g_variant_hash, g_variant_equal,
3410 (GDestroyNotify ) g_variant_unref,
3413 for (i = 0; i < G_N_ELEMENTS (items); i++)
3419 tree = tree_instance_new (NULL, 0);
3420 items[i] = tree_instance_get_gvariant (tree);
3421 tree_instance_free (tree);
3423 for (j = 0; j < i; j++)
3424 if (g_variant_equal (items[i], items[j]))
3426 g_variant_unref (items[i]);
3430 g_hash_table_insert (table,
3431 g_variant_ref_sink (items[i]),
3432 GINT_TO_POINTER (i));
3435 for (i = 0; i < G_N_ELEMENTS (items); i++)
3439 result = g_hash_table_lookup (table, items[i]);
3440 g_assert_cmpint (GPOINTER_TO_INT (result), ==, i);
3443 g_hash_table_unref (table);
3445 g_variant_type_info_assert_no_infos ();
3451 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
3452 # define native16(x) x, 0
3453 # define swapped16(x) 0, x
3455 # define native16(x) 0, x
3456 # define swapped16(x) x, 0
3458 /* all kinds of of crazy randomised testing already performed on the
3459 * byteswapper in the /gvariant/serialiser/byteswap test and all kinds
3460 * of crazy randomised testing performed against the serialiser
3461 * normalisation functions in the /gvariant/serialiser/fuzz/ tests.
3463 * just test a few simple cases here to make sure they each work
3465 guchar valid_data[] = { 'a', '\0', swapped16(66), 2,
3467 'b', '\0', swapped16(77), 2,
3469 guchar corrupt_data[] = { 'a', '\0', swapped16(66), 2,
3471 'b', '\0', swapped16(77), 2,
3473 GVariant *value, *swapped;
3474 gchar *string, *string2;
3478 value = g_variant_new_from_data (G_VARIANT_TYPE ("a(sn)"),
3479 valid_data, sizeof valid_data, TRUE,
3481 swapped = g_variant_byteswap (value);
3482 g_variant_unref (value);
3483 g_assert (g_variant_get_size (swapped) == 13);
3484 string = g_variant_print (swapped, FALSE);
3485 g_variant_unref (swapped);
3486 g_assert_cmpstr (string, ==, "[('a', 66), ('b', 77)]");
3489 /* untrusted but valid */
3490 value = g_variant_new_from_data (G_VARIANT_TYPE ("a(sn)"),
3491 valid_data, sizeof valid_data, FALSE,
3493 swapped = g_variant_byteswap (value);
3494 g_variant_unref (value);
3495 g_assert (g_variant_get_size (swapped) == 13);
3496 string = g_variant_print (swapped, FALSE);
3497 g_variant_unref (swapped);
3498 g_assert_cmpstr (string, ==, "[('a', 66), ('b', 77)]");
3501 /* untrusted, invalid */
3502 value = g_variant_new_from_data (G_VARIANT_TYPE ("a(sn)"),
3503 corrupt_data, sizeof corrupt_data, FALSE,
3505 string = g_variant_print (value, FALSE);
3506 swapped = g_variant_byteswap (value);
3507 g_variant_unref (value);
3508 g_assert (g_variant_get_size (swapped) == 13);
3509 value = g_variant_byteswap (swapped);
3510 g_variant_unref (swapped);
3511 string2 = g_variant_print (value, FALSE);
3512 g_assert (g_variant_get_size (value) == 13);
3513 g_variant_unref (value);
3514 g_assert_cmpstr (string, ==, string2);
3528 tree = tree_instance_new (NULL, 3);
3529 value = tree_instance_get_gvariant (tree);
3530 tree_instance_free (tree);
3532 pt = g_variant_print (value, TRUE);
3533 p = g_variant_print (value, FALSE);
3535 parsed = g_variant_parse (NULL, pt, NULL, NULL, NULL);
3536 res = g_variant_print (parsed, FALSE);
3537 g_assert_cmpstr (p, ==, res);
3538 g_variant_unref (parsed);
3541 parsed = g_variant_parse (g_variant_get_type (value), p,
3543 res = g_variant_print (parsed, TRUE);
3544 g_assert_cmpstr (pt, ==, res);
3545 g_variant_unref (parsed);
3548 g_variant_unref (value);
3558 for (i = 0; i < 100; i++)
3569 for (i = 0; i < 256; i++)
3572 val = g_variant_new_string (str);
3573 p = g_variant_print (val, FALSE);
3574 g_variant_unref (val);
3576 val = g_variant_parse (NULL, p, NULL, NULL, NULL);
3577 p2 = g_variant_print (val, FALSE);
3579 g_assert_cmpstr (str, ==, g_variant_get_string (val, NULL));
3580 g_assert_cmpstr (p, ==, p2);
3582 g_variant_unref (val);
3587 /* another mini test */
3592 value = g_variant_parse (G_VARIANT_TYPE_INT32, "1 2 3", NULL, &end, NULL);
3593 g_assert_cmpint (g_variant_get_int32 (value), ==, 1);
3594 /* make sure endptr returning works */
3595 g_assert_cmpstr (end, ==, " 2 3");
3596 g_variant_unref (value);
3599 g_variant_type_info_assert_no_infos ();
3603 test_parse_failures (void)
3605 const gchar *test[] = {
3606 "[1, 2,", "6:", "expected value",
3607 "", "0:", "expected value",
3608 "(1, 2,", "6:", "expected value",
3609 "<1", "2:", "expected `>'",
3610 "[]", "0-2:", "unable to infer",
3611 "(,", "1:", "expected value",
3612 "[4,'']", "1-2,3-5:", "common type",
3613 "[4, '', 5]", "1-2,4-6:", "common type",
3614 "['', 4, 5]", "1-3,5-6:", "common type",
3615 "[4, 5, '']", "1-2,7-9:", "common type",
3616 "[[4], [], ['']]", "1-4,10-14:", "common type",
3617 "[[], [4], ['']]", "5-8,10-14:", "common type",
3618 "just", "4:", "expected value",
3619 "nothing", "0-7:", "unable to infer",
3620 "just [4, '']", "6-7,9-11:", "common type",
3621 "[[4,'']]", "2-3,4-6:", "common type",
3622 "([4,''],)", "2-3,4-6:", "common type",
3624 "{}", "0-2:", "unable to infer",
3625 "{[1,2],[3,4]}", "0-13:", "basic types",
3626 "{[1,2]:[3,4]}", "0-13:", "basic types",
3627 "justt", "0-5:", "unknown keyword",
3628 "nothng", "0-6:", "unknown keyword",
3629 "uint33", "0-6:", "unknown keyword",
3630 "@mi just ''", "9-11:", "can not parse as",
3631 "@ai ['']", "5-7:", "can not parse as",
3632 "@(i) ('',)", "6-8:", "can not parse as",
3633 "[[], 5]", "1-3,5-6:", "common type",
3634 "[[5], 5]", "1-4,6-7:", "common type",
3635 "5 5", "2:", "expected end of input",
3636 "[5, [5, '']]", "5-6,8-10:", "common type",
3637 "@i just 5", "3-9:", "can not parse as",
3638 "@i nothing", "3-10:", "can not parse as",
3639 "@i []", "3-5:", "can not parse as",
3640 "@i ()", "3-5:", "can not parse as",
3641 "@ai (4,)", "4-8:", "can not parse as",
3642 "@(i) []", "5-7:", "can not parse as",
3643 "(5 5)", "3:", "expected `,'",
3644 "[5 5]", "3:", "expected `,' or `]'",
3645 "(5, 5 5)", "6:", "expected `,' or `)'",
3646 "[5, 5 5]", "6:", "expected `,' or `]'",
3647 "<@i []>", "4-6:", "can not parse as",
3648 "<[5 5]>", "4:", "expected `,' or `]'",
3649 "{[4,''],5}", "2-3,4-6:", "common type",
3650 "{5,[4,'']}", "4-5,6-8:", "common type",
3651 "@i {1,2}", "3-8:", "can not parse as",
3652 "{@i '', 5}", "4-6:", "can not parse as",
3653 "{5, @i ''}", "7-9:", "can not parse as",
3654 "@ai {}", "4-6:", "can not parse as",
3655 "{@i '': 5}", "4-6:", "can not parse as",
3656 "{5: @i ''}", "7-9:", "can not parse as",
3657 "{<4,5}", "3:", "expected `>'",
3658 "{4,<5}", "5:", "expected `>'",
3659 "{4,5,6}", "4:", "expected `}'",
3660 "{5 5}", "3:", "expected `:' or `,'",
3661 "{4: 5: 6}", "5:", "expected `,' or `}'",
3662 "{4:5,<6:7}", "7:", "expected `>'",
3663 "{4:5,6:<7}", "9:", "expected `>'",
3664 "{4:5,6 7}", "7:", "expected `:'",
3665 "@o 'foo'", "3-8:", "object path",
3666 "@g 'zzz'", "3-8:", "signature",
3667 "@i true", "3-7:", "can not parse as",
3668 "@z 4", "0-2:", "invalid type",
3669 "@a* []", "0-3:", "definite",
3670 "@ai [3 3]", "7:", "expected `,' or `]'",
3671 "18446744073709551616", "0-20:", "too big for any type",
3672 "-18446744073709551616", "0-21:", "too big for any type",
3673 "byte 256", "5-8:", "out of range for type",
3674 "byte -1", "5-7:", "out of range for type",
3675 "int16 32768", "6-11:", "out of range for type",
3676 "int16 -32769", "6-12:", "out of range for type",
3677 "uint16 -1", "7-9:", "out of range for type",
3678 "uint16 65536", "7-12:", "out of range for type",
3679 "2147483648", "0-10:", "out of range for type",
3680 "-2147483649", "0-11:", "out of range for type",
3681 "uint32 -1", "7-9:", "out of range for type",
3682 "uint32 4294967296", "7-17:", "out of range for type",
3683 "@x 9223372036854775808", "3-22:", "out of range for type",
3684 "@x -9223372036854775809", "3-23:", "out of range for type",
3685 "@t -1", "3-5:", "out of range for type",
3686 "@t 18446744073709551616", "3-23:", "too big for any type",
3687 "handle 2147483648", "7-17:", "out of range for type",
3688 "handle -2147483649", "7-18:", "out of range for type",
3689 "1.798e308", "0-9:", "too big for any type",
3690 "37.5a488", "4-5:", "invalid character",
3691 "0x7ffgf", "5-6:", "invalid character",
3692 "07758", "4-5:", "invalid character",
3693 "123a5", "3-4:", "invalid character",
3694 "@ai 123", "4-7:", "can not parse as",
3695 "'\"\\'", "0-4:", "unterminated string",
3696 "'\"\\'\\", "0-5:", "unterminated string",
3697 "boolean 4", "8-9:", "can not parse as",
3698 "int32 true", "6-10:", "can not parse as",
3699 "[double 5, int32 5]", "1-9,11-18:", "common type",
3700 "string 4", "7-8:", "can not parse as"
3704 for (i = 0; i < G_N_ELEMENTS (test); i += 3)
3706 GError *error = NULL;
3709 value = g_variant_parse (NULL, test[i], NULL, NULL, &error);
3710 g_assert (value == NULL);
3712 if (!strstr (error->message, test[i+2]))
3713 g_error ("test %d: Can't find `%s' in `%s'", i / 3,
3714 test[i+2], error->message);
3716 if (!g_str_has_prefix (error->message, test[i+1]))
3717 g_error ("test %d: Expected location `%s' in `%s'", i / 3,
3718 test[i+1], error->message);
3720 g_error_free (error);
3725 test_parse_positional (void)
3728 check_and_free (g_variant_new_parsed ("[('one', 1), (%s, 2),"
3729 " ('three', %i)]", "two", 3),
3730 "[('one', 1), ('two', 2), ('three', 3)]");
3731 value = g_variant_new_parsed ("[('one', 1), (%s, 2),"
3732 " ('three', %u)]", "two", 3);
3733 g_assert (g_variant_is_of_type (value, G_VARIANT_TYPE ("a(su)")));
3734 check_and_free (value, "[('one', 1), ('two', 2), ('three', 3)]");
3735 check_and_free (g_variant_new_parsed ("{%s:%i}", "one", 1), "{'one': 1}");
3737 if (do_failed_test ("*GVariant format string*"))
3739 g_variant_new_parsed ("%z");
3743 if (do_failed_test ("*can not parse as*"))
3745 g_variant_new_parsed ("uint32 %i", 2);
3749 if (do_failed_test ("*expected GVariant of type `i'*"))
3751 g_variant_new_parsed ("%@i", g_variant_new_uint32 (2));
3757 main (int argc, char **argv)
3761 g_test_init (&argc, &argv, NULL);
3763 g_test_add_func ("/gvariant/type", test_gvarianttype);
3764 g_test_add_func ("/gvariant/typeinfo", test_gvarianttypeinfo);
3765 g_test_add_func ("/gvariant/serialiser/maybe", test_maybes);
3766 g_test_add_func ("/gvariant/serialiser/array", test_arrays);
3767 g_test_add_func ("/gvariant/serialiser/tuple", test_tuples);
3768 g_test_add_func ("/gvariant/serialiser/variant", test_variants);
3769 g_test_add_func ("/gvariant/serialiser/strings", test_strings);
3770 g_test_add_func ("/gvariant/serialiser/byteswap", test_byteswaps);
3772 for (i = 1; i <= 20; i += 4)
3776 testname = g_strdup_printf ("/gvariant/serialiser/fuzz/%d%%", i);
3777 g_test_add_data_func (testname, GINT_TO_POINTER (i),
3778 (gpointer) test_fuzzes);
3782 g_test_add_func ("/gvariant/utf8", test_utf8);
3783 g_test_add_func ("/gvariant/containers", test_containers);
3784 g_test_add_func ("/gvariant/format-strings", test_format_strings);
3785 g_test_add_func ("/gvariant/invalid-varargs", test_invalid_varargs);
3786 g_test_add_func ("/gvariant/varargs", test_varargs);
3787 g_test_add_func ("/gvariant/valist", test_valist);
3788 g_test_add_func ("/gvariant/builder-memory", test_builder_memory);
3789 g_test_add_func ("/gvariant/hashing", test_hashing);
3790 g_test_add_func ("/gvariant/byteswap", test_gv_byteswap);
3791 g_test_add_func ("/gvariant/parser", test_parses);
3792 g_test_add_func ("/gvariant/parse-failures", test_parse_failures);
3793 g_test_add_func ("/gvariant/parse-positional", test_parse_positional);
3795 return g_test_run ();