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)
26 randomly (gdouble prob)
28 return g_test_rand_double_range (0, 1) < prob;
33 append_tuple_type_string (GString *, GString *, gboolean, gint);
35 /* append a random GVariantType to a GString
36 * append a description of the type to another GString
37 * return what the type is
40 append_type_string (GString *string,
45 if (!depth-- || randomly (0.3))
47 gchar b = BASIC[g_test_rand_int_range (0, N_BASIC - definite)];
48 g_string_append_c (string, b);
49 g_string_append_c (description, b);
54 return g_variant_type_copy (G_VARIANT_TYPE_BOOLEAN);
56 return g_variant_type_copy (G_VARIANT_TYPE_BYTE);
58 return g_variant_type_copy (G_VARIANT_TYPE_INT16);
60 return g_variant_type_copy (G_VARIANT_TYPE_UINT16);
62 return g_variant_type_copy (G_VARIANT_TYPE_INT32);
64 return g_variant_type_copy (G_VARIANT_TYPE_UINT32);
66 return g_variant_type_copy (G_VARIANT_TYPE_INT64);
68 return g_variant_type_copy (G_VARIANT_TYPE_UINT64);
70 return g_variant_type_copy (G_VARIANT_TYPE_HANDLE);
72 return g_variant_type_copy (G_VARIANT_TYPE_DOUBLE);
74 return g_variant_type_copy (G_VARIANT_TYPE_STRING);
76 return g_variant_type_copy (G_VARIANT_TYPE_OBJECT_PATH);
78 return g_variant_type_copy (G_VARIANT_TYPE_SIGNATURE);
80 return g_variant_type_copy (G_VARIANT_TYPE_BASIC);
82 g_assert_not_reached ();
89 switch (g_test_rand_int_range (0, definite ? 5 : 7))
93 GVariantType *element;
95 g_string_append_c (string, 'a');
96 g_string_append (description, "a of ");
97 element = append_type_string (string, description,
99 result = g_variant_type_new_array (element);
100 g_variant_type_free (element);
103 g_assert (g_variant_type_is_array (result));
108 GVariantType *element;
110 g_string_append_c (string, 'm');
111 g_string_append (description, "m of ");
112 element = append_type_string (string, description,
114 result = g_variant_type_new_maybe (element);
115 g_variant_type_free (element);
118 g_assert (g_variant_type_is_maybe (result));
122 result = append_tuple_type_string (string, description,
125 g_assert (g_variant_type_is_tuple (result));
130 GVariantType *key, *value;
132 g_string_append_c (string, '{');
133 g_string_append (description, "e of [");
134 key = append_type_string (string, description, definite, 0);
135 g_string_append (description, ", ");
136 value = append_type_string (string, description, definite, depth);
137 g_string_append_c (description, ']');
138 g_string_append_c (string, '}');
139 result = g_variant_type_new_dict_entry (key, value);
140 g_variant_type_free (key);
141 g_variant_type_free (value);
144 g_assert (g_variant_type_is_dict_entry (result));
148 g_string_append_c (string, 'v');
149 g_string_append_c (description, 'V');
150 result = g_variant_type_copy (G_VARIANT_TYPE_VARIANT);
151 g_assert (g_variant_type_equal (result, G_VARIANT_TYPE_VARIANT));
155 g_string_append_c (string, '*');
156 g_string_append_c (description, 'S');
157 result = g_variant_type_copy (G_VARIANT_TYPE_ANY);
158 g_assert (g_variant_type_equal (result, G_VARIANT_TYPE_ANY));
162 g_string_append_c (string, 'r');
163 g_string_append_c (description, 'R');
164 result = g_variant_type_copy (G_VARIANT_TYPE_TUPLE);
165 g_assert (g_variant_type_is_tuple (result));
169 g_assert_not_reached ();
176 static GVariantType *
177 append_tuple_type_string (GString *string,
178 GString *description,
182 GVariantType *result, *other_result;
183 GVariantType **types;
187 g_string_append_c (string, '(');
188 g_string_append (description, "t of [");
190 size = g_test_rand_int_range (0, 20);
191 types = g_new (GVariantType *, size + 1);
193 for (i = 0; i < size; i++)
195 types[i] = append_type_string (string, description, definite, depth);
198 g_string_append (description, ", ");
203 g_string_append_c (description, ']');
204 g_string_append_c (string, ')');
206 result = g_variant_type_new_tuple ((gpointer) types, size);
207 other_result = g_variant_type_new_tuple ((gpointer) types, -1);
208 g_assert (g_variant_type_equal (result, other_result));
209 g_variant_type_free (other_result);
210 for (i = 0; i < size; i++)
211 g_variant_type_free (types[i]);
217 /* given a valid type string, make it invalid */
219 invalid_mutation (const gchar *type_string)
221 gboolean have_parens, have_braces;
223 /* it's valid, so '(' implies ')' and same for '{' and '}' */
224 have_parens = strchr (type_string, '(') != NULL;
225 have_braces = strchr (type_string, '{') != NULL;
227 if (have_parens && have_braces && randomly (0.3))
229 /* swap a paren and a brace */
235 new = g_strdup (type_string);
245 /* count number of parens/braces */
246 while ((pp = strchr (pp + 1, p))) np++;
247 while ((bp = strchr (bp + 1, b))) nb++;
249 /* randomly pick one of each */
250 np = g_test_rand_int_range (0, np) + 1;
251 nb = g_test_rand_int_range (0, nb) + 1;
255 while (np--) pp = strchr (pp + 1, p);
256 while (nb--) bp = strchr (bp + 1, b);
259 g_assert (*bp == b && *pp == p);
266 if ((have_parens || have_braces) && randomly (0.3))
268 /* drop a paren/brace */
275 if (randomly (0.5)) p = '('; else p = ')';
277 if (randomly (0.5)) p = '{'; else p = '}';
279 new = g_strdup (type_string);
283 while ((pp = strchr (pp + 1, p))) np++;
284 np = g_test_rand_int_range (0, np) + 1;
286 while (np--) pp = strchr (pp + 1, p);
298 /* else, perform a random mutation at a random point */
306 /* insert a paren/brace */
308 if (randomly (0.5)) p = '('; else p = ')';
310 if (randomly (0.5)) p = '{'; else p = '}';
312 else if (randomly (0.5))
315 p = INVALIDS[g_test_rand_int_range (0, N_INVALIDS)];
324 length = strlen (type_string);
325 new = g_malloc (length + 2);
326 n = g_test_rand_int_range (0, length);
327 memcpy (new, type_string, n);
329 memcpy (new + n + 1, type_string + n, length - n);
330 new[length + 1] = '\0';
336 /* describe a type using the same language as is generated
337 * while generating the type with append_type_string
340 describe_type (const GVariantType *type)
344 if (g_variant_type_is_container (type))
346 g_assert (!g_variant_type_is_basic (type));
348 if (g_variant_type_is_array (type))
350 gchar *subtype = describe_type (g_variant_type_element (type));
351 result = g_strdup_printf ("a of %s", subtype);
354 else if (g_variant_type_is_maybe (type))
356 gchar *subtype = describe_type (g_variant_type_element (type));
357 result = g_strdup_printf ("m of %s", subtype);
360 else if (g_variant_type_is_tuple (type))
362 if (!g_variant_type_equal (type, G_VARIANT_TYPE_TUPLE))
364 const GVariantType *sub;
369 string = g_string_new ("t of [");
371 length = g_variant_type_n_items (type);
372 sub = g_variant_type_first (type);
373 for (i = 0; i < length; i++)
375 gchar *subtype = describe_type (sub);
376 g_string_append (string, subtype);
379 if ((sub = g_variant_type_next (sub)))
380 g_string_append (string, ", ");
382 g_assert (sub == NULL);
383 g_string_append_c (string, ']');
385 result = g_string_free (string, FALSE);
388 result = g_strdup ("R");
390 else if (g_variant_type_is_dict_entry (type))
392 gchar *key, *value, *key2, *value2;
394 key = describe_type (g_variant_type_key (type));
395 value = describe_type (g_variant_type_value (type));
396 key2 = describe_type (g_variant_type_first (type));
397 value2 = describe_type (
398 g_variant_type_next (g_variant_type_first (type)));
399 g_assert (g_variant_type_next (g_variant_type_next (
400 g_variant_type_first (type))) == NULL);
401 g_assert_cmpstr (key, ==, key2);
402 g_assert_cmpstr (value, ==, value2);
403 result = g_strjoin ("", "e of [", key, ", ", value, "]", NULL);
409 else if (g_variant_type_equal (type, G_VARIANT_TYPE_VARIANT))
411 result = g_strdup ("V");
414 g_assert_not_reached ();
418 if (g_variant_type_is_definite (type))
420 g_assert (g_variant_type_is_basic (type));
422 if (g_variant_type_equal (type, G_VARIANT_TYPE_BOOLEAN))
423 result = g_strdup ("b");
424 else if (g_variant_type_equal (type, G_VARIANT_TYPE_BYTE))
425 result = g_strdup ("y");
426 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT16))
427 result = g_strdup ("n");
428 else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT16))
429 result = g_strdup ("q");
430 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32))
431 result = g_strdup ("i");
432 else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT32))
433 result = g_strdup ("u");
434 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT64))
435 result = g_strdup ("x");
436 else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT64))
437 result = g_strdup ("t");
438 else if (g_variant_type_equal (type, G_VARIANT_TYPE_HANDLE))
439 result = g_strdup ("h");
440 else if (g_variant_type_equal (type, G_VARIANT_TYPE_DOUBLE))
441 result = g_strdup ("d");
442 else if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING))
443 result = g_strdup ("s");
444 else if (g_variant_type_equal (type, G_VARIANT_TYPE_OBJECT_PATH))
445 result = g_strdup ("o");
446 else if (g_variant_type_equal (type, G_VARIANT_TYPE_SIGNATURE))
447 result = g_strdup ("g");
449 g_assert_not_reached ();
453 if (g_variant_type_equal (type, G_VARIANT_TYPE_ANY))
455 result = g_strdup ("S");
457 else if (g_variant_type_equal (type, G_VARIANT_TYPE_BASIC))
459 result = g_strdup ("?");
462 g_assert_not_reached ();
469 /* given a type string, replace one of the indefinite type characters in
470 * it with a matching type (possibly the same type).
473 generate_subtype (const gchar *type_string)
475 GVariantType *replacement;
476 GString *result, *junk;
477 gint length, n = 0, l;
479 result = g_string_new (NULL);
480 junk = g_string_new (NULL);
482 /* count the number of indefinite type characters */
483 for (length = 0; type_string[length]; length++)
484 n += type_string[length] == 'r' ||
485 type_string[length] == '?' ||
486 type_string[length] == '*';
487 /* length now is strlen (type_string) */
489 /* pick one at random to replace */
490 n = g_test_rand_int_range (0, n) + 1;
494 while (n--) l += strcspn (type_string + l + 1, "r?*") + 1;
495 g_assert (type_string[l] == 'r' ||
496 type_string[l] == '?' ||
497 type_string[l] == '*');
499 /* store up to that point in a GString */
500 g_string_append_len (result, type_string, l);
502 /* then store the replacement in the GString */
503 if (type_string[l] == 'r')
504 replacement = append_tuple_type_string (result, junk, FALSE, 3);
506 else if (type_string[l] == '?')
507 replacement = append_type_string (result, junk, FALSE, 0);
509 else if (type_string[l] == '*')
510 replacement = append_type_string (result, junk, FALSE, 3);
513 g_assert_not_reached ();
515 /* ensure the replacement has the proper type */
516 g_assert (g_variant_type_is_subtype_of (replacement,
517 (gpointer) &type_string[l]));
519 /* store the rest from the original type string */
520 g_string_append (result, type_string + l + 1);
522 g_variant_type_free (replacement);
523 g_string_free (junk, TRUE);
525 return g_string_free (result, FALSE);
530 const GVariantType *type;
531 struct typestack *parent;
534 /* given an indefinite type string, replace one of the indefinite
535 * characters in it with a matching type and ensure that the result is a
536 * subtype of the original. repeat.
539 subtype_check (const gchar *type_string,
540 struct typestack *parent_ts)
542 struct typestack ts, *node;
546 subtype = generate_subtype (type_string);
548 ts.type = G_VARIANT_TYPE (subtype);
549 ts.parent = parent_ts;
551 for (node = &ts; node; node = node->parent)
553 /* this type should be a subtype of each parent type */
554 g_assert (g_variant_type_is_subtype_of (ts.type, node->type));
556 /* it should only be a supertype when it is exactly equal */
557 g_assert (g_variant_type_is_subtype_of (node->type, ts.type) ==
558 g_variant_type_equal (ts.type, node->type));
563 if (!g_variant_type_is_definite (ts.type) && depth < 5)
565 /* the type is still indefinite and we haven't repeated too many
566 * times. go once more.
569 subtype_check (subtype, &ts);
576 test_gvarianttype (void)
580 for (i = 0; i < 2000; i++)
582 GString *type_string, *description;
583 GVariantType *type, *other_type;
584 const GVariantType *ctype;
588 type_string = g_string_new (NULL);
589 description = g_string_new (NULL);
591 /* generate a random type, its type string and a description
593 * exercises type constructor functions and g_variant_type_copy()
595 type = append_type_string (type_string, description, FALSE, 6);
597 /* convert the type string to a type and ensure that it is equal
598 * to the one produced with the type constructor routines
600 ctype = G_VARIANT_TYPE (type_string->str);
601 g_assert (g_variant_type_equal (ctype, type));
602 g_assert (g_variant_type_is_subtype_of (ctype, type));
603 g_assert (g_variant_type_is_subtype_of (type, ctype));
605 /* check if the type is indefinite */
606 if (!g_variant_type_is_definite (type))
608 struct typestack ts = { type, NULL };
610 /* if it is indefinite, then replace one of the indefinite
611 * characters with a matching type and ensure that the result
612 * is a subtype of the original type. repeat.
614 subtype_check (type_string->str, &ts);
617 /* ensure that no indefinite characters appear */
618 g_assert (strcspn (type_string->str, "r?*") == type_string->len);
621 /* describe the type.
623 * exercises the type iterator interface
625 desc = describe_type (type);
627 /* make sure the description matches */
628 g_assert_cmpstr (desc, ==, description->str);
631 /* make an invalid mutation to the type and make sure the type
632 * validation routines catch it */
633 invalid = invalid_mutation (type_string->str);
634 g_assert (g_variant_type_string_is_valid (type_string->str));
635 g_assert (!g_variant_type_string_is_valid (invalid));
638 /* concatenate another type to the type string and ensure that
639 * the result is recognised as being invalid
641 other_type = append_type_string (type_string, description, FALSE, 2);
643 g_string_free (description, TRUE);
644 g_string_free (type_string, TRUE);
645 g_variant_type_free (other_type);
646 g_variant_type_free (type);
650 #define ALIGNED(x, y) (((x + (y - 1)) / y) * y)
652 /* do our own calculation of the fixed_size and alignment of a type
653 * using a simple algorithm to make sure the "fancy" one in the
654 * implementation is correct.
657 calculate_type_info (const GVariantType *type,
661 if (g_variant_type_is_array (type) ||
662 g_variant_type_is_maybe (type))
664 calculate_type_info (g_variant_type_element (type), NULL, alignment);
669 else if (g_variant_type_is_tuple (type) ||
670 g_variant_type_is_dict_entry (type))
672 if (g_variant_type_n_items (type))
674 const GVariantType *sub;
683 sub = g_variant_type_first (type);
689 calculate_type_info (sub, &this_fs, &this_al);
691 al = MAX (al, this_al);
701 size = ALIGNED (size, this_al);
705 while ((sub = g_variant_type_next (sub)));
707 size = ALIGNED (size, al);
728 if (g_variant_type_equal (type, G_VARIANT_TYPE_BOOLEAN) ||
729 g_variant_type_equal (type, G_VARIANT_TYPE_BYTE))
734 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT16) ||
735 g_variant_type_equal (type, G_VARIANT_TYPE_UINT16))
740 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32) ||
741 g_variant_type_equal (type, G_VARIANT_TYPE_UINT32) ||
742 g_variant_type_equal (type, G_VARIANT_TYPE_HANDLE))
747 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT64) ||
748 g_variant_type_equal (type, G_VARIANT_TYPE_UINT64) ||
749 g_variant_type_equal (type, G_VARIANT_TYPE_DOUBLE))
753 else if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING) ||
754 g_variant_type_equal (type, G_VARIANT_TYPE_OBJECT_PATH) ||
755 g_variant_type_equal (type, G_VARIANT_TYPE_SIGNATURE))
760 else if (g_variant_type_equal (type, G_VARIANT_TYPE_VARIANT))
766 g_assert_not_reached ();
776 /* same as the describe_type() function above, but iterates over
777 * typeinfo instead of types.
780 describe_info (GVariantTypeInfo *info)
784 switch (g_variant_type_info_get_type_char (info))
786 case G_VARIANT_TYPE_INFO_CHAR_MAYBE:
790 element = describe_info (g_variant_type_info_element (info));
791 result = g_strdup_printf ("m of %s", element);
796 case G_VARIANT_TYPE_INFO_CHAR_ARRAY:
800 element = describe_info (g_variant_type_info_element (info));
801 result = g_strdup_printf ("a of %s", element);
806 case G_VARIANT_TYPE_INFO_CHAR_TUPLE:
808 const gchar *sep = "";
813 string = g_string_new ("t of [");
814 length = g_variant_type_info_n_members (info);
816 for (i = 0; i < length; i++)
818 const GVariantMemberInfo *minfo;
821 g_string_append (string, sep);
824 minfo = g_variant_type_info_member_info (info, i);
825 subtype = describe_info (minfo->type_info);
826 g_string_append (string, subtype);
830 g_string_append_c (string, ']');
832 result = g_string_free (string, FALSE);
836 case G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY:
838 const GVariantMemberInfo *keyinfo, *valueinfo;
841 g_assert_cmpint (g_variant_type_info_n_members (info), ==, 2);
842 keyinfo = g_variant_type_info_member_info (info, 0);
843 valueinfo = g_variant_type_info_member_info (info, 1);
844 key = describe_info (keyinfo->type_info);
845 value = describe_info (valueinfo->type_info);
846 result = g_strjoin ("", "e of [", key, ", ", value, "]", NULL);
852 case G_VARIANT_TYPE_INFO_CHAR_VARIANT:
853 result = g_strdup ("V");
857 result = g_strdup (g_variant_type_info_get_type_string (info));
858 g_assert_cmpint (strlen (result), ==, 1);
865 /* check that the O(1) method of calculating offsets meshes with the
866 * results of simple iteration.
869 check_offsets (GVariantTypeInfo *info,
870 const GVariantType *type)
875 length = g_variant_type_info_n_members (info);
876 g_assert_cmpint (length, ==, g_variant_type_n_items (type));
878 /* the 'flavour' is the low order bits of the ending point of
879 * variable-size items in the tuple. this lets us test that the type
880 * info is correct for various starting alignments.
882 for (flavour = 0; flavour < 8; flavour++)
884 const GVariantType *subtype;
885 gsize last_offset_index;
890 subtype = g_variant_type_first (type);
891 last_offset_index = -1;
895 /* go through the tuple, keeping track of our position */
896 for (i = 0; i < length; i++)
901 calculate_type_info (subtype, &fixed_size, &alignment);
903 position = ALIGNED (position, alignment);
905 /* compare our current aligned position (ie: the start of this
906 * item) to the start offset that would be calculated if we
910 const GVariantMemberInfo *member;
913 member = g_variant_type_info_member_info (info, i);
914 g_assert_cmpint (member->i, ==, last_offset_index);
916 /* do the calculation using the typeinfo */
922 /* did we reach the same spot? */
923 g_assert_cmpint (start, ==, position);
928 /* fixed size. add that size. */
929 position += fixed_size;
933 /* variable size. do the flavouring. */
934 while ((position & 0x7) != flavour)
937 /* and store the offset, just like it would be in the
940 last_offset = position;
945 subtype = g_variant_type_next (subtype);
948 /* make sure we used up exactly all the types */
949 g_assert (subtype == NULL);
954 test_gvarianttypeinfo (void)
958 for (i = 0; i < 2000; i++)
960 GString *type_string, *description;
961 gsize fixed_size1, fixed_size2;
962 guint alignment1, alignment2;
963 GVariantTypeInfo *info;
967 type_string = g_string_new (NULL);
968 description = g_string_new (NULL);
971 type = append_type_string (type_string, description, TRUE, 6);
973 /* create a typeinfo for it */
974 info = g_variant_type_info_get (type);
976 /* make sure the typeinfo has the right type string */
977 g_assert_cmpstr (g_variant_type_info_get_type_string (info), ==,
980 /* calculate the alignment and fixed size, compare to the
981 * typeinfo's calculations
983 calculate_type_info (type, &fixed_size1, &alignment1);
984 g_variant_type_info_query (info, &alignment2, &fixed_size2);
985 g_assert_cmpint (fixed_size1, ==, fixed_size2);
986 g_assert_cmpint (alignment1, ==, alignment2 + 1);
988 /* test the iteration functions over typeinfo structures by
989 * "describing" the typeinfo and verifying equality.
991 desc = describe_info (info);
992 g_assert_cmpstr (desc, ==, description->str);
994 /* do extra checks for containers */
995 if (g_variant_type_is_array (type) ||
996 g_variant_type_is_maybe (type))
998 const GVariantType *element;
1002 element = g_variant_type_element (type);
1003 calculate_type_info (element, &efs1, &ea1);
1004 g_variant_type_info_query_element (info, &ea2, &efs2);
1005 g_assert_cmpint (efs1, ==, efs2);
1006 g_assert_cmpint (ea1, ==, ea2 + 1);
1008 g_assert_cmpint (ea1, ==, alignment1);
1009 g_assert_cmpint (0, ==, fixed_size1);
1011 else if (g_variant_type_is_tuple (type) ||
1012 g_variant_type_is_dict_entry (type))
1014 /* make sure the "magic constants" are working */
1015 check_offsets (info, type);
1018 g_string_free (type_string, TRUE);
1019 g_string_free (description, TRUE);
1020 g_variant_type_info_unref (info);
1021 g_variant_type_free (type);
1025 g_variant_type_info_assert_no_infos ();
1028 #define MAX_FIXED_MULTIPLIER 256
1029 #define MAX_INSTANCE_SIZE 1024
1030 #define MAX_ARRAY_CHILDREN 128
1031 #define MAX_TUPLE_CHILDREN 128
1033 /* this function generates a random type such that all characteristics
1034 * that are "interesting" to the serialiser are tested.
1036 * this basically means:
1037 * - test different alignments
1038 * - test variable sized items and fixed sized items
1039 * - test different fixed sizes
1042 random_type_string (void)
1044 const guchar base_types[] = "ynix";
1047 base_type = base_types[g_test_rand_int_range (0, 4)];
1049 if (g_test_rand_bit ())
1050 /* construct a fixed-sized type */
1052 char type_string[MAX_FIXED_MULTIPLIER];
1056 multiplier = g_test_rand_int_range (1, sizeof type_string - 1);
1058 type_string[i++] = '(';
1059 while (multiplier--)
1060 type_string[i++] = base_type;
1061 type_string[i++] = ')';
1063 return g_strndup (type_string, i);
1066 /* construct a variable-sized type */
1068 char type_string[2] = { 'a', base_type };
1070 return g_strndup (type_string, 2);
1076 GVariantTypeInfo *type_info;
1079 gboolean is_fixed_sized;
1083 #define INSTANCE_MAGIC 1287582829
1087 static RandomInstance *
1088 random_instance (GVariantTypeInfo *type_info)
1090 RandomInstance *instance;
1092 instance = g_slice_new (RandomInstance);
1094 if (type_info == NULL)
1096 gchar *str = random_type_string ();
1097 instance->type_info = g_variant_type_info_get (G_VARIANT_TYPE (str));
1101 instance->type_info = g_variant_type_info_ref (type_info);
1103 instance->seed = g_test_rand_int ();
1105 g_variant_type_info_query (instance->type_info,
1106 &instance->alignment,
1109 instance->is_fixed_sized = instance->size != 0;
1111 if (!instance->is_fixed_sized)
1112 instance->size = g_test_rand_int_range (0, MAX_INSTANCE_SIZE);
1114 instance->magic = INSTANCE_MAGIC;
1120 random_instance_free (RandomInstance *instance)
1122 g_variant_type_info_unref (instance->type_info);
1123 g_slice_free (RandomInstance, instance);
1127 append_instance_size (RandomInstance *instance,
1130 *offset += (-*offset) & instance->alignment;
1131 *offset += instance->size;
1135 random_instance_write (RandomInstance *instance,
1141 g_assert_cmpint ((gsize) buffer & instance->alignment, ==, 0);
1143 rand = g_rand_new_with_seed (instance->seed);
1144 for (i = 0; i < instance->size; i++)
1145 buffer[i] = g_rand_int (rand);
1150 append_instance_data (RandomInstance *instance,
1153 while (((gsize) *buffer) & instance->alignment)
1154 *(*buffer)++ = '\0';
1156 random_instance_write (instance, *buffer);
1157 *buffer += instance->size;
1161 random_instance_assert (RandomInstance *instance,
1168 g_assert_cmpint ((gsize) buffer & instance->alignment, ==, 0);
1169 g_assert_cmpint (size, ==, instance->size);
1171 rand = g_rand_new_with_seed (instance->seed);
1172 for (i = 0; i < instance->size; i++)
1174 guchar byte = g_rand_int (rand);
1176 g_assert (buffer[i] == byte);
1180 return i == instance->size;
1184 random_instance_check (RandomInstance *instance,
1191 g_assert_cmpint ((gsize) buffer & instance->alignment, ==, 0);
1193 if (size != instance->size)
1196 rand = g_rand_new_with_seed (instance->seed);
1197 for (i = 0; i < instance->size; i++)
1198 if (buffer[i] != (guchar) g_rand_int (rand))
1202 return i == instance->size;
1206 random_instance_filler (GVariantSerialised *serialised,
1209 RandomInstance *instance = data;
1211 g_assert (instance->magic == INSTANCE_MAGIC);
1213 if (serialised->type_info == NULL)
1214 serialised->type_info = instance->type_info;
1216 if (serialised->size == 0)
1217 serialised->size = instance->size;
1219 g_assert (serialised->type_info == instance->type_info);
1220 g_assert (serialised->size == instance->size);
1222 if (serialised->data)
1223 random_instance_write (instance, serialised->data);
1227 calculate_offset_size (gsize body_size,
1233 if (body_size + n_offsets <= G_MAXUINT8)
1236 if (body_size + 2 * n_offsets <= G_MAXUINT16)
1239 if (body_size + 4 * n_offsets <= G_MAXUINT32)
1242 /* the test case won't generate anything bigger */
1243 g_assert_not_reached ();
1247 flavoured_malloc (gsize size, gsize flavour)
1249 g_assert (flavour < 8);
1254 return ((gchar *) g_malloc (size + flavour)) + flavour;
1258 flavoured_free (gpointer data)
1260 g_free ((gpointer) (((gsize) data) & ~7));
1264 append_offset (guchar **offset_ptr,
1270 guchar bytes[sizeof (gsize)];
1274 tmpvalue.integer = GSIZE_TO_LE (offset);
1275 memcpy (*offset_ptr, tmpvalue.bytes, offset_size);
1276 *offset_ptr += offset_size;
1280 prepend_offset (guchar **offset_ptr,
1286 guchar bytes[sizeof (gsize)];
1290 *offset_ptr -= offset_size;
1291 tmpvalue.integer = GSIZE_TO_LE (offset);
1292 memcpy (*offset_ptr, tmpvalue.bytes, offset_size);
1298 GVariantTypeInfo *type_info;
1299 RandomInstance *instance;
1303 instance = random_instance (NULL);
1306 const gchar *element;
1309 element = g_variant_type_info_get_type_string (instance->type_info);
1310 tmp = g_strdup_printf ("m%s", element);
1311 type_info = g_variant_type_info_get (G_VARIANT_TYPE (tmp));
1315 needed_size = g_variant_serialiser_needed_size (type_info,
1316 random_instance_filler,
1318 g_assert_cmpint (needed_size, ==, 0);
1320 needed_size = g_variant_serialiser_needed_size (type_info,
1321 random_instance_filler,
1322 (gpointer *) &instance, 1);
1324 if (instance->is_fixed_sized)
1325 g_assert_cmpint (needed_size, ==, instance->size);
1327 g_assert_cmpint (needed_size, ==, instance->size + 1);
1332 ptr = data = g_malloc (needed_size);
1333 append_instance_data (instance, &ptr);
1335 if (!instance->is_fixed_sized)
1338 g_assert_cmpint (ptr - data, ==, needed_size);
1345 alignment = instance->alignment + 1;
1347 for (flavour = 0; flavour < 8; flavour += alignment)
1349 GVariantSerialised serialised;
1350 GVariantSerialised child;
1352 serialised.type_info = type_info;
1353 serialised.data = flavoured_malloc (needed_size, flavour);
1354 serialised.size = needed_size;
1356 g_variant_serialiser_serialise (serialised,
1357 random_instance_filler,
1358 (gpointer *) &instance, 1);
1359 child = g_variant_serialised_get_child (serialised, 0);
1360 g_assert (child.type_info == instance->type_info);
1361 random_instance_assert (instance, child.data, child.size);
1362 g_variant_type_info_unref (child.type_info);
1363 flavoured_free (serialised.data);
1367 g_variant_type_info_unref (type_info);
1368 random_instance_free (instance);
1377 for (i = 0; i < 1000; i++)
1380 g_variant_type_info_assert_no_infos ();
1386 GVariantTypeInfo *element_info;
1387 GVariantTypeInfo *array_info;
1388 RandomInstance **instances;
1395 gchar *element_type, *array_type;
1397 element_type = random_type_string ();
1398 array_type = g_strdup_printf ("a%s", element_type);
1400 element_info = g_variant_type_info_get (G_VARIANT_TYPE (element_type));
1401 array_info = g_variant_type_info_get (G_VARIANT_TYPE (array_type));
1402 g_assert (g_variant_type_info_element (array_info) == element_info);
1404 g_free (element_type);
1405 g_free (array_type);
1411 n_children = g_test_rand_int_range (0, MAX_ARRAY_CHILDREN);
1412 instances = g_new (RandomInstance *, n_children);
1413 for (i = 0; i < n_children; i++)
1414 instances[i] = random_instance (element_info);
1417 needed_size = g_variant_serialiser_needed_size (array_info,
1418 random_instance_filler,
1419 (gpointer *) instances,
1423 gsize element_fixed_size;
1424 gsize body_size = 0;
1427 for (i = 0; i < n_children; i++)
1428 append_instance_size (instances[i], &body_size);
1430 g_variant_type_info_query (element_info, NULL, &element_fixed_size);
1432 if (!element_fixed_size)
1434 offset_size = calculate_offset_size (body_size, n_children);
1436 if (offset_size == 0)
1442 g_assert_cmpint (needed_size, ==, body_size + n_children * offset_size);
1446 guchar *offset_ptr, *body_ptr;
1449 body_ptr = data = g_malloc (needed_size);
1450 offset_ptr = body_ptr + needed_size - offset_size * n_children;
1452 for (i = 0; i < n_children; i++)
1454 append_instance_data (instances[i], &body_ptr);
1455 append_offset (&offset_ptr, body_ptr - data, offset_size);
1458 g_assert (body_ptr == data + needed_size - offset_size * n_children);
1459 g_assert (offset_ptr == data + needed_size);
1467 g_variant_type_info_query (array_info, &alignment, NULL);
1470 for (flavour = 0; flavour < 8; flavour += alignment)
1472 GVariantSerialised serialised;
1474 serialised.type_info = array_info;
1475 serialised.data = flavoured_malloc (needed_size, flavour);
1476 serialised.size = needed_size;
1478 g_variant_serialiser_serialise (serialised, random_instance_filler,
1479 (gpointer *) instances, n_children);
1481 g_assert (memcmp (serialised.data, data, serialised.size) == 0);
1482 g_assert (g_variant_serialised_n_children (serialised) == n_children);
1484 for (i = 0; i < n_children; i++)
1486 GVariantSerialised child;
1488 child = g_variant_serialised_get_child (serialised, i);
1489 g_assert (child.type_info == instances[i]->type_info);
1490 random_instance_assert (instances[i], child.data, child.size);
1491 g_variant_type_info_unref (child.type_info);
1494 flavoured_free (serialised.data);
1501 for (i = 0; i < n_children; i++)
1502 random_instance_free (instances[i]);
1506 g_variant_type_info_unref (element_info);
1507 g_variant_type_info_unref (array_info);
1516 for (i = 0; i < 100; i++)
1519 g_variant_type_info_assert_no_infos ();
1525 GVariantTypeInfo *type_info;
1526 RandomInstance **instances;
1527 gboolean fixed_size;
1534 n_children = g_test_rand_int_range (0, MAX_TUPLE_CHILDREN);
1535 instances = g_new (RandomInstance *, n_children);
1538 GString *type_string;
1544 type_string = g_string_new ("(");
1545 for (i = 0; i < n_children; i++)
1549 instances[i] = random_instance (NULL);
1551 alignment |= instances[i]->alignment;
1552 if (!instances[i]->is_fixed_sized)
1555 str = g_variant_type_info_get_type_string (instances[i]->type_info);
1556 g_string_append (type_string, str);
1558 g_string_append_c (type_string, ')');
1560 type_info = g_variant_type_info_get (G_VARIANT_TYPE (type_string->str));
1561 g_string_free (type_string, TRUE);
1564 needed_size = g_variant_serialiser_needed_size (type_info,
1565 random_instance_filler,
1566 (gpointer *) instances,
1569 gsize body_size = 0;
1573 for (i = 0; i < n_children; i++)
1575 append_instance_size (instances[i], &body_size);
1577 if (i != n_children - 1 && !instances[i]->is_fixed_sized)
1583 body_size += (-body_size) & alignment;
1585 g_assert ((body_size == 0) == (n_children == 0));
1586 if (n_children == 0)
1590 offset_size = calculate_offset_size (body_size, offsets);
1591 g_assert_cmpint (needed_size, ==, body_size + offsets * offset_size);
1599 body_ptr = data = g_malloc (needed_size);
1600 ofs_ptr = body_ptr + needed_size;
1602 for (i = 0; i < n_children; i++)
1604 append_instance_data (instances[i], &body_ptr);
1606 if (i != n_children - 1 && !instances[i]->is_fixed_sized)
1607 prepend_offset (&ofs_ptr, body_ptr - data, offset_size);
1612 while (((gsize) body_ptr) & alignment)
1615 g_assert ((body_ptr == data) == (n_children == 0));
1616 if (n_children == 0)
1622 g_assert (body_ptr == ofs_ptr);
1631 for (flavour = 0; flavour < 8; flavour += alignment)
1633 GVariantSerialised serialised;
1635 serialised.type_info = type_info;
1636 serialised.data = flavoured_malloc (needed_size, flavour);
1637 serialised.size = needed_size;
1639 g_variant_serialiser_serialise (serialised, random_instance_filler,
1640 (gpointer *) instances, n_children);
1642 g_assert (memcmp (serialised.data, data, serialised.size) == 0);
1643 g_assert (g_variant_serialised_n_children (serialised) == n_children);
1645 for (i = 0; i < n_children; i++)
1647 GVariantSerialised child;
1649 child = g_variant_serialised_get_child (serialised, i);
1650 g_assert (child.type_info == instances[i]->type_info);
1651 random_instance_assert (instances[i], child.data, child.size);
1652 g_variant_type_info_unref (child.type_info);
1655 flavoured_free (serialised.data);
1662 for (i = 0; i < n_children; i++)
1663 random_instance_free (instances[i]);
1667 g_variant_type_info_unref (type_info);
1676 for (i = 0; i < 100; i++)
1679 g_variant_type_info_assert_no_infos ();
1685 GVariantTypeInfo *type_info;
1686 RandomInstance *instance;
1687 const gchar *type_string;
1692 type_info = g_variant_type_info_get (G_VARIANT_TYPE_VARIANT);
1693 instance = random_instance (NULL);
1695 type_string = g_variant_type_info_get_type_string (instance->type_info);
1696 len = strlen (type_string);
1698 needed_size = g_variant_serialiser_needed_size (type_info,
1699 random_instance_filler,
1700 (gpointer *) &instance, 1);
1702 g_assert_cmpint (needed_size, ==, instance->size + 1 + len);
1707 ptr = data = g_malloc (needed_size);
1708 append_instance_data (instance, &ptr);
1710 memcpy (ptr, type_string, len);
1713 g_assert (data + needed_size == ptr);
1717 /* variants are 8-aligned, so no extra flavouring */
1718 GVariantSerialised serialised;
1719 GVariantSerialised child;
1721 serialised.type_info = type_info;
1722 serialised.data = flavoured_malloc (needed_size, 0);
1723 serialised.size = needed_size;
1725 g_variant_serialiser_serialise (serialised, random_instance_filler,
1726 (gpointer *) &instance, 1);
1728 g_assert (memcmp (serialised.data, data, serialised.size) == 0);
1729 g_assert (g_variant_serialised_n_children (serialised) == 1);
1731 child = g_variant_serialised_get_child (serialised, 0);
1732 g_assert (child.type_info == instance->type_info);
1733 random_instance_check (instance, child.data, child.size);
1735 g_variant_type_info_unref (child.type_info);
1736 flavoured_free (serialised.data);
1739 g_variant_type_info_unref (type_info);
1740 random_instance_free (instance);
1745 test_variants (void)
1749 for (i = 0; i < 100; i++)
1752 g_variant_type_info_assert_no_infos ();
1765 #define is_objpath is_string | 2
1766 #define is_sig is_string | 4
1768 { is_nval, 0, NULL },
1769 { is_nval, 13, "hello\xffworld!" },
1770 { is_string, 13, "hello world!" },
1771 { is_nval, 13, "hello world\0" },
1772 { is_nval, 13, "hello\0world!" },
1773 { is_nval, 12, "hello world!" },
1775 { is_objpath, 2, "/" },
1776 { is_objpath, 3, "/a" },
1777 { is_string, 3, "//" },
1778 { is_objpath, 11, "/some/path" },
1779 { is_string, 12, "/some/path/" },
1780 { is_nval, 11, "/some\0path" },
1781 { is_string, 11, "/some\\path" },
1782 { is_string, 12, "/some//path" },
1783 { is_string, 12, "/some-/path" },
1787 { is_sig, 5, "(si)" },
1788 { is_string, 4, "(si" },
1789 { is_string, 2, "*" },
1790 { is_sig, 3, "ai" },
1791 { is_string, 3, "mi" },
1792 { is_string, 2, "r" },
1793 { is_sig, 15, "(yyy{sv}ssiai)" },
1794 { is_string, 16, "(yyy{yv}ssiai))" },
1795 { is_string, 15, "(yyy{vv}ssiai)" },
1796 { is_string, 15, "(yyy{sv)ssiai}" }
1800 for (i = 0; i < G_N_ELEMENTS (test_cases); i++)
1804 flags = g_variant_serialiser_is_string (test_cases[i].data,
1808 flags |= g_variant_serialiser_is_object_path (test_cases[i].data,
1812 flags |= g_variant_serialiser_is_signature (test_cases[i].data,
1816 g_assert (flags == test_cases[i].flags);
1820 typedef struct _TreeInstance TreeInstance;
1821 struct _TreeInstance
1823 GVariantTypeInfo *info;
1825 TreeInstance **children;
1836 static GVariantType *
1837 make_random_definite_type (int depth)
1839 GString *description;
1840 GString *type_string;
1843 description = g_string_new (NULL);
1844 type_string = g_string_new (NULL);
1845 type = append_type_string (type_string, description, TRUE, depth);
1846 g_string_free (description, TRUE);
1847 g_string_free (type_string, TRUE);
1853 make_random_string (gchar *string,
1855 const GVariantType *type)
1859 /* create strings that are valid signature strings */
1860 #define good_chars "bynqiuxthdsog"
1862 for (i = 0; i < size - 1; i++)
1863 string[i] = good_chars[g_test_rand_int_range (0, strlen (good_chars))];
1866 /* in case we need an object path, prefix a '/' */
1867 if (*g_variant_type_peek_string (type) == 'o')
1873 static TreeInstance *
1874 tree_instance_new (const GVariantType *type,
1877 const GVariantType *child_type = NULL;
1878 GVariantType *mytype = NULL;
1879 TreeInstance *instance;
1880 gboolean is_tuple_type;
1883 type = mytype = make_random_definite_type (depth);
1885 instance = g_slice_new (TreeInstance);
1886 instance->info = g_variant_type_info_get (type);
1887 instance->children = NULL;
1888 instance->n_children = 0;
1889 instance->data_size = 0;
1891 is_tuple_type = FALSE;
1893 switch (*g_variant_type_peek_string (type))
1895 case G_VARIANT_TYPE_INFO_CHAR_MAYBE:
1896 instance->n_children = g_test_rand_int_range (0, 2);
1897 child_type = g_variant_type_element (type);
1900 case G_VARIANT_TYPE_INFO_CHAR_ARRAY:
1901 instance->n_children = g_test_rand_int_range (0, MAX_ARRAY_CHILDREN);
1902 child_type = g_variant_type_element (type);
1905 case G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY:
1906 case G_VARIANT_TYPE_INFO_CHAR_TUPLE:
1907 instance->n_children = g_variant_type_n_items (type);
1908 child_type = g_variant_type_first (type);
1909 is_tuple_type = TRUE;
1912 case G_VARIANT_TYPE_INFO_CHAR_VARIANT:
1913 instance->n_children = 1;
1918 instance->data.integer = g_test_rand_int_range (0, 2);
1919 instance->data_size = 1;
1923 instance->data.integer = g_test_rand_int ();
1924 instance->data_size = 1;
1928 instance->data.integer = g_test_rand_int ();
1929 instance->data_size = 2;
1932 case 'i': case 'u': case 'h':
1933 instance->data.integer = g_test_rand_int ();
1934 instance->data_size = 4;
1938 instance->data.integer = g_test_rand_int ();
1939 instance->data.integer <<= 32;
1940 instance->data.integer |= (guint32) g_test_rand_int ();
1941 instance->data_size = 8;
1945 instance->data.floating = g_test_rand_double ();
1946 instance->data_size = 8;
1949 case 's': case 'o': case 'g':
1950 instance->data_size = g_test_rand_int_range (10, 20);
1951 make_random_string (instance->data.string, instance->data_size, type);
1955 if (instance->data_size == 0)
1956 /* no data -> it is a container */
1960 instance->children = g_new (TreeInstance *, instance->n_children);
1962 for (i = 0; i < instance->n_children; i++)
1964 instance->children[i] = tree_instance_new (child_type, depth - 1);
1967 child_type = g_variant_type_next (child_type);
1970 g_assert (!is_tuple_type || child_type == NULL);
1973 g_variant_type_free (mytype);
1979 tree_instance_free (TreeInstance *instance)
1983 g_variant_type_info_unref (instance->info);
1984 for (i = 0; i < instance->n_children; i++)
1985 tree_instance_free (instance->children[i]);
1986 g_free (instance->children);
1987 g_slice_free (TreeInstance, instance);
1990 static gboolean i_am_writing_byteswapped;
1993 tree_filler (GVariantSerialised *serialised,
1996 TreeInstance *instance = data;
1998 if (serialised->type_info == NULL)
1999 serialised->type_info = instance->info;
2001 if (instance->data_size == 0)
2002 /* is a container */
2004 if (serialised->size == 0)
2006 g_variant_serialiser_needed_size (instance->info, tree_filler,
2007 (gpointer *) instance->children,
2008 instance->n_children);
2010 if (serialised->data)
2011 g_variant_serialiser_serialise (*serialised, tree_filler,
2012 (gpointer *) instance->children,
2013 instance->n_children);
2018 if (serialised->size == 0)
2019 serialised->size = instance->data_size;
2021 if (serialised->data)
2023 switch (instance->data_size)
2026 *serialised->data = instance->data.integer;
2031 guint16 value = instance->data.integer;
2033 if (i_am_writing_byteswapped)
2034 value = GUINT16_SWAP_LE_BE (value);
2036 *(guint16 *) serialised->data = value;
2042 guint32 value = instance->data.integer;
2044 if (i_am_writing_byteswapped)
2045 value = GUINT32_SWAP_LE_BE (value);
2047 *(guint32 *) serialised->data = value;
2053 guint64 value = instance->data.integer;
2055 if (i_am_writing_byteswapped)
2056 value = GUINT64_SWAP_LE_BE (value);
2058 *(guint64 *) serialised->data = value;
2063 memcpy (serialised->data,
2064 instance->data.string,
2065 instance->data_size);
2073 check_tree (TreeInstance *instance,
2074 GVariantSerialised serialised)
2076 if (instance->info != serialised.type_info)
2079 if (instance->data_size == 0)
2080 /* is a container */
2084 if (g_variant_serialised_n_children (serialised) !=
2085 instance->n_children)
2088 for (i = 0; i < instance->n_children; i++)
2090 GVariantSerialised child;
2091 gpointer data = NULL;
2094 child = g_variant_serialised_get_child (serialised, i);
2095 if (child.size && child.data == NULL)
2096 child.data = data = g_malloc0 (child.size);
2097 ok = check_tree (instance->children[i], child);
2098 g_variant_type_info_unref (child.type_info);
2110 switch (instance->data_size)
2113 g_assert (serialised.size == 1);
2114 return *(guint8 *) serialised.data ==
2115 (guint8) instance->data.integer;
2118 g_assert (serialised.size == 2);
2119 return *(guint16 *) serialised.data ==
2120 (guint16) instance->data.integer;
2123 g_assert (serialised.size == 4);
2124 return *(guint32 *) serialised.data ==
2125 (guint32) instance->data.integer;
2128 g_assert (serialised.size == 8);
2129 return *(guint64 *) serialised.data ==
2130 (guint64) instance->data.integer;
2133 if (serialised.size != instance->data_size)
2136 return memcmp (serialised.data,
2137 instance->data.string,
2138 instance->data_size) == 0;
2144 serialise_tree (TreeInstance *tree,
2145 GVariantSerialised *serialised)
2147 GVariantSerialised empty = { };
2149 *serialised = empty;
2150 tree_filler (serialised, tree);
2151 serialised->data = g_malloc (serialised->size);
2152 tree_filler (serialised, tree);
2156 test_byteswap (void)
2158 GVariantSerialised one, two;
2161 tree = tree_instance_new (NULL, 3);
2162 serialise_tree (tree, &one);
2164 i_am_writing_byteswapped = TRUE;
2165 serialise_tree (tree, &two);
2166 i_am_writing_byteswapped = FALSE;
2168 g_variant_serialised_byteswap (two);
2170 g_assert_cmpint (one.size, ==, two.size);
2171 g_assert (memcmp (one.data, two.data, one.size) == 0);
2173 tree_instance_free (tree);
2179 test_byteswaps (void)
2183 for (i = 0; i < 200; i++)
2186 g_variant_type_info_assert_no_infos ();
2190 test_fuzz (gdouble *fuzziness)
2192 GVariantSerialised serialised;
2195 /* make an instance */
2196 tree = tree_instance_new (NULL, 3);
2199 serialise_tree (tree, &serialised);
2201 g_assert (g_variant_serialised_is_normal (serialised));
2202 g_assert (check_tree (tree, serialised));
2204 if (serialised.size)
2206 gboolean fuzzed = FALSE;
2213 for (i = 0; i < serialised.size; i++)
2214 if (randomly (*fuzziness))
2216 serialised.data[i] += g_test_rand_int_range (1, 256);
2221 /* at least one byte in the serialised data has changed.
2223 * this means that at least one of the following is true:
2225 * - the serialised data now represents a different value:
2226 * check_tree() will return FALSE
2228 * - the serialised data is in non-normal form:
2229 * g_variant_serialiser_is_normal() will return FALSE
2231 * we always do both checks to increase exposure of the serialiser
2234 a = g_variant_serialised_is_normal (serialised);
2235 b = check_tree (tree, serialised);
2237 g_assert (!a || !b);
2240 tree_instance_free (tree);
2241 g_free (serialised.data);
2246 test_fuzzes (gpointer data)
2251 fuzziness = GPOINTER_TO_INT (data) / 100.;
2253 for (i = 0; i < 200; i++)
2254 test_fuzz (&fuzziness);
2256 g_variant_type_info_assert_no_infos ();
2260 tree_instance_get_gvariant (TreeInstance *tree)
2262 const GVariantType *type;
2265 type = (GVariantType *) g_variant_type_info_get_type_string (tree->info);
2267 switch (g_variant_type_info_get_type_char (tree->info))
2269 case G_VARIANT_TYPE_INFO_CHAR_MAYBE:
2271 const GVariantType *child_type;
2274 if (tree->n_children)
2275 child = tree_instance_get_gvariant (tree->children[0]);
2279 child_type = g_variant_type_element (type);
2281 if (child != NULL && randomly (0.5))
2284 result = g_variant_new_maybe (child_type, child);
2288 case G_VARIANT_TYPE_INFO_CHAR_ARRAY:
2290 const GVariantType *child_type;
2291 GVariant **children;
2294 children = g_new (GVariant *, tree->n_children);
2295 for (i = 0; i < tree->n_children; i++)
2296 children[i] = tree_instance_get_gvariant (tree->children[i]);
2298 child_type = g_variant_type_element (type);
2300 if (i > 0 && randomly (0.5))
2303 result = g_variant_new_array (child_type, children, tree->n_children);
2308 case G_VARIANT_TYPE_INFO_CHAR_TUPLE:
2310 GVariant **children;
2313 children = g_new (GVariant *, tree->n_children);
2314 for (i = 0; i < tree->n_children; i++)
2315 children[i] = tree_instance_get_gvariant (tree->children[i]);
2317 result = g_variant_new_tuple (children, tree->n_children);
2322 case G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY:
2324 GVariant *key, *val;
2326 g_assert (tree->n_children == 2);
2328 key = tree_instance_get_gvariant (tree->children[0]);
2329 val = tree_instance_get_gvariant (tree->children[1]);
2331 result = g_variant_new_dict_entry (key, val);
2335 case G_VARIANT_TYPE_INFO_CHAR_VARIANT:
2339 g_assert (tree->n_children == 1);
2341 value = tree_instance_get_gvariant (tree->children[0]);
2342 result = g_variant_new_variant (value);
2347 result = g_variant_new_boolean (tree->data.integer > 0);
2351 result = g_variant_new_byte (tree->data.integer);
2355 result = g_variant_new_int16 (tree->data.integer);
2359 result = g_variant_new_uint16 (tree->data.integer);
2363 result = g_variant_new_int32 (tree->data.integer);
2367 result = g_variant_new_uint32 (tree->data.integer);
2371 result = g_variant_new_int64 (tree->data.integer);
2375 result = g_variant_new_uint64 (tree->data.integer);
2379 result = g_variant_new_handle (tree->data.integer);
2383 result = g_variant_new_double (tree->data.floating);
2387 result = g_variant_new_string (tree->data.string);
2391 result = g_variant_new_object_path (tree->data.string);
2395 result = g_variant_new_signature (tree->data.string);
2399 g_assert_not_reached ();
2406 tree_instance_check_gvariant (TreeInstance *tree,
2409 const GVariantType *type;
2411 type = (GVariantType *) g_variant_type_info_get_type_string (tree->info);
2412 g_assert (g_variant_is_of_type (value, type));
2414 switch (g_variant_type_info_get_type_char (tree->info))
2416 case G_VARIANT_TYPE_INFO_CHAR_MAYBE:
2421 child = g_variant_get_maybe (value);
2423 if (child != NULL && tree->n_children == 1)
2424 equal = tree_instance_check_gvariant (tree->children[0], child);
2425 else if (child == NULL && tree->n_children == 0)
2431 g_variant_unref (child);
2437 case G_VARIANT_TYPE_INFO_CHAR_ARRAY:
2438 case G_VARIANT_TYPE_INFO_CHAR_TUPLE:
2439 case G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY:
2443 if (g_variant_n_children (value) != tree->n_children)
2446 for (i = 0; i < tree->n_children; i++)
2451 child = g_variant_get_child_value (value, i);
2452 equal = tree_instance_check_gvariant (tree->children[i], child);
2453 g_variant_unref (child);
2463 case G_VARIANT_TYPE_INFO_CHAR_VARIANT:
2465 const gchar *str1, *str2;
2469 child = g_variant_get_variant (value);
2470 str1 = g_variant_get_type_string (child);
2471 str2 = g_variant_type_info_get_type_string (tree->children[0]->info);
2472 /* GVariant only keeps one copy of type strings around */
2473 equal = str1 == str2 &&
2474 tree_instance_check_gvariant (tree->children[0], child);
2476 g_variant_unref (child);
2483 return g_variant_get_boolean (value) == tree->data.integer;
2486 return g_variant_get_byte (value) == (guchar) tree->data.integer;
2489 return g_variant_get_int16 (value) == (gint16) tree->data.integer;
2492 return g_variant_get_uint16 (value) == (guint16) tree->data.integer;
2495 return g_variant_get_int32 (value) == (gint32) tree->data.integer;
2498 return g_variant_get_uint32 (value) == (guint32) tree->data.integer;
2501 return g_variant_get_int64 (value) == (gint64) tree->data.integer;
2504 return g_variant_get_uint64 (value) == (guint64) tree->data.integer;
2507 return g_variant_get_handle (value) == (gint32) tree->data.integer;
2511 gdouble floating = g_variant_get_double (value);
2513 return memcmp (&floating, &tree->data.floating, sizeof floating) == 0;
2519 return strcmp (g_variant_get_string (value, NULL),
2520 tree->data.string) == 0;
2523 g_assert_not_reached ();
2528 tree_instance_build_gvariant (TreeInstance *tree,
2529 GVariantBuilder *builder,
2532 const GVariantType *type;
2534 type = (GVariantType *) g_variant_type_info_get_type_string (tree->info);
2536 if (g_variant_type_is_container (type))
2540 /* force GVariantBuilder to guess the type half the time */
2541 if (guess_ok && randomly (0.5))
2543 if (g_variant_type_is_array (type) && tree->n_children)
2544 type = G_VARIANT_TYPE_ARRAY;
2546 if (g_variant_type_is_maybe (type) && tree->n_children)
2547 type = G_VARIANT_TYPE_MAYBE;
2549 if (g_variant_type_is_tuple (type))
2550 type = G_VARIANT_TYPE_TUPLE;
2552 if (g_variant_type_is_dict_entry (type))
2553 type = G_VARIANT_TYPE_DICT_ENTRY;
2558 g_variant_builder_open (builder, type);
2560 for (i = 0; i < tree->n_children; i++)
2561 tree_instance_build_gvariant (tree->children[i], builder, guess_ok);
2563 g_variant_builder_close (builder);
2566 g_variant_builder_add_value (builder, tree_instance_get_gvariant (tree));
2571 tree_instance_check_iter (TreeInstance *tree,
2576 value = g_variant_iter_next_value (iter);
2578 if (g_variant_is_container (value))
2582 iter = g_variant_iter_new (value);
2583 g_variant_unref (value);
2585 if (g_variant_iter_n_children (iter) != tree->n_children)
2587 g_variant_iter_free (iter);
2591 for (i = 0; i < tree->n_children; i++)
2592 if (!tree_instance_check_iter (tree->children[i], iter))
2594 g_variant_iter_free (iter);
2598 g_assert (g_variant_iter_next_value (iter) == NULL);
2599 g_variant_iter_free (iter);
2608 equal = tree_instance_check_gvariant (tree, value);
2609 g_variant_unref (value);
2616 test_container (void)
2622 tree = tree_instance_new (NULL, 3);
2623 value = g_variant_ref_sink (tree_instance_get_gvariant (tree));
2625 s1 = g_variant_print (value, TRUE);
2626 g_assert (tree_instance_check_gvariant (tree, value));
2628 g_variant_get_data (value);
2630 s2 = g_variant_print (value, TRUE);
2631 g_assert (tree_instance_check_gvariant (tree, value));
2633 g_assert_cmpstr (s1, ==, s2);
2635 if (g_variant_is_container (value))
2637 GVariantBuilder builder;
2643 g_variant_builder_init (&builder, G_VARIANT_TYPE_VARIANT);
2644 tree_instance_build_gvariant (tree, &builder, TRUE);
2645 built = g_variant_builder_end (&builder);
2646 g_variant_ref_sink (built);
2647 g_variant_get_data (built);
2648 val = g_variant_get_variant (built);
2650 s3 = g_variant_print (val, TRUE);
2651 g_assert_cmpstr (s1, ==, s3);
2653 g_variant_iter_init (&iter, built);
2654 g_assert (tree_instance_check_iter (tree, &iter));
2655 g_assert (g_variant_iter_next_value (&iter) == NULL);
2657 g_variant_unref (built);
2658 g_variant_unref (val);
2662 tree_instance_free (tree);
2663 g_variant_unref (value);
2671 const gchar invalid[] = "hello\xffworld";
2674 /* ensure that the test data is not valid utf8... */
2675 g_assert (!g_utf8_validate (invalid, -1, NULL));
2677 /* load the data untrusted */
2678 value = g_variant_new_from_data (G_VARIANT_TYPE_STRING,
2679 invalid, sizeof invalid,
2682 /* ensure that the problem is caught and we get valid UTF-8 */
2683 g_assert (g_utf8_validate (g_variant_get_string (value, NULL), -1, NULL));
2684 g_variant_unref (value);
2687 /* now load it trusted */
2688 value = g_variant_new_from_data (G_VARIANT_TYPE_STRING,
2689 invalid, sizeof invalid,
2692 /* ensure we get the invalid data (ie: make sure that time wasn't
2693 * wasted on validating data that was marked as trusted)
2695 g_assert (g_variant_get_string (value, NULL) == invalid);
2696 g_variant_unref (value);
2700 test_containers (void)
2704 for (i = 0; i < 100; i++)
2709 g_variant_type_info_assert_no_infos ();
2713 test_format_strings (void)
2718 g_assert (g_variant_format_string_scan ("i", NULL, &end) && *end == '\0');
2719 g_assert (g_variant_format_string_scan ("@i", NULL, &end) && *end == '\0');
2720 g_assert (g_variant_format_string_scan ("@ii", NULL, &end) && *end == 'i');
2721 g_assert (g_variant_format_string_scan ("^a&s", NULL, &end) && *end == '\0');
2722 g_assert (g_variant_format_string_scan ("(^as)", NULL, &end) &&
2724 g_assert (!g_variant_format_string_scan ("(^s)", NULL, &end));
2725 g_assert (!g_variant_format_string_scan ("(^a)", NULL, &end));
2726 g_assert (!g_variant_format_string_scan ("(z)", NULL, &end));
2727 g_assert (!g_variant_format_string_scan ("az", NULL, &end));
2728 g_assert (!g_variant_format_string_scan ("{**}", NULL, &end));
2729 g_assert (!g_variant_format_string_scan ("{@**}", NULL, &end));
2730 g_assert (g_variant_format_string_scan ("{@y*}", NULL, &end) &&
2732 g_assert (g_variant_format_string_scan ("{yv}", NULL, &end) &&
2734 g_assert (!g_variant_format_string_scan ("{&?v}", NULL, &end));
2735 g_assert (g_variant_format_string_scan ("{@?v}", NULL, &end) &&
2737 g_assert (!g_variant_format_string_scan ("{&@sv}", NULL, &end));
2738 g_assert (!g_variant_format_string_scan ("{@&sv}", NULL, &end));
2739 g_assert (g_variant_format_string_scan ("{&sv}", NULL, &end) &&
2741 g_assert (!g_variant_format_string_scan ("{vv}", NULL, &end));
2742 g_assert (!g_variant_format_string_scan ("{y}", NULL, &end));
2743 g_assert (!g_variant_format_string_scan ("{yyy}", NULL, &end));
2744 g_assert (!g_variant_format_string_scan ("{ya}", NULL, &end));
2745 g_assert (g_variant_format_string_scan ("&s", NULL, &end) && *end == '\0');
2746 g_assert (!g_variant_format_string_scan ("&as", NULL, &end));
2747 g_assert (!g_variant_format_string_scan ("@z", NULL, &end));
2748 g_assert (!g_variant_format_string_scan ("az", NULL, &end));
2749 g_assert (!g_variant_format_string_scan ("a&s", NULL, &end));
2751 type = g_variant_format_string_scan_type ("mm(@xy^a&s*?@?)", NULL, &end);
2752 g_assert (type && *end == '\0');
2753 g_assert (g_variant_type_equal (type, G_VARIANT_TYPE ("mm(xyas*?\?)")));
2754 g_variant_type_free (type);
2756 type = g_variant_format_string_scan_type ("mm(@xy^a&*?@?)", NULL, NULL);
2757 g_assert (type == NULL);
2761 exit_on_abort (int signal)
2767 do_failed_test (const gchar *pattern)
2769 if (g_test_trap_fork (1000000, G_TEST_TRAP_SILENCE_STDERR))
2771 signal (SIGABRT, exit_on_abort);
2775 g_test_trap_assert_failed ();
2776 g_test_trap_assert_stderr (pattern);
2782 test_invalid_varargs (void)
2784 if (do_failed_test ("*GVariant format string*"))
2786 g_variant_new ("z");
2790 if (do_failed_test ("*valid GVariant format string as a prefix*"))
2794 g_variant_new_va ("z", &end, NULL);
2798 if (do_failed_test ("*type of `q' but * has a type of `y'*"))
2800 g_variant_get (g_variant_new ("y", 'a'), "q");
2806 check_and_free (GVariant *value,
2809 gchar *valstr = g_variant_print (value, FALSE);
2810 g_assert_cmpstr (str, ==, valstr);
2811 g_variant_unref (value);
2819 GVariantBuilder array;
2821 g_variant_builder_init (&array, G_VARIANT_TYPE_ARRAY);
2822 g_variant_builder_add (&array, "{sv}", "size",
2823 g_variant_new ("(ii)", 800, 600));
2824 g_variant_builder_add (&array, "{sv}", "title",
2825 g_variant_new_string ("Test case"));
2826 g_variant_builder_add_value (&array,
2827 g_variant_new_dict_entry (g_variant_new_string ("temperature"),
2828 g_variant_new_variant (
2829 g_variant_new_double (37.5))));
2830 check_and_free (g_variant_new ("(ma{sv}m(a{sv})ma{sv}ii)",
2831 NULL, FALSE, NULL, &array, 7777, 8888),
2832 "(nothing, nothing, {'size': <(800, 600)>, "
2833 "'title': <'Test case'>, "
2834 "'temperature': <37.5>}, "
2837 check_and_free (g_variant_new ("(imimimmimmimmi)",
2844 "(123, nothing, 123, nothing, just nothing, 123)");
2846 check_and_free (g_variant_new ("(ybnixd)",
2847 'a', 1, 22, 33, (guint64) 44, 5.5),
2848 "(0x61, true, 22, 33, 44, 5.5)");
2850 check_and_free (g_variant_new ("(@y?*rv)",
2851 g_variant_new ("y", 'a'),
2852 g_variant_new ("y", 'b'),
2853 g_variant_new ("y", 'c'),
2854 g_variant_new ("(y)", 'd'),
2855 g_variant_new ("y", 'e')),
2856 "(0x61, 0x62, 0x63, (0x64,), <byte 0x65>)");
2860 GVariantBuilder array;
2867 g_variant_builder_init (&array, G_VARIANT_TYPE_ARRAY);
2868 for (i = 0; i < 100; i++)
2870 number = g_strdup_printf ("%d", i);
2871 g_variant_builder_add (&array, "s", number);
2875 value = g_variant_builder_end (&array);
2876 g_variant_iter_init (&iter, value);
2879 while (g_variant_iter_loop (&iter, "s", &number))
2881 gchar *check = g_strdup_printf ("%d", i++);
2882 g_assert_cmpstr (number, ==, check);
2885 g_assert (number == NULL);
2886 g_assert (i == 100);
2888 g_variant_unref (value);
2890 g_variant_builder_init (&array, G_VARIANT_TYPE_ARRAY);
2891 for (i = 0; i < 100; i++)
2892 g_variant_builder_add (&array, "mi", i % 2 == 0, i);
2893 value = g_variant_builder_end (&array);
2896 g_variant_iter_init (&iter, value);
2897 while (g_variant_iter_loop (&iter, "mi", NULL, &val))
2898 g_assert (val == i++ || val == 0);
2899 g_assert (i == 100);
2902 g_variant_iter_init (&iter, value);
2903 while (g_variant_iter_loop (&iter, "mi", &just, &val))
2910 g_assert (val == this);
2915 g_assert (val == 0);
2918 g_assert (i == 100);
2920 g_variant_unref (value);
2924 const gchar *strvector[] = {"/hello", "/world", NULL};
2925 const gchar *test_strs[] = {"/foo", "/bar", "/baz" };
2926 GVariantBuilder builder;
2927 GVariantIter *array;
2935 g_variant_builder_init (&builder, G_VARIANT_TYPE ("ao"));
2936 g_variant_builder_add (&builder, "o", "/foo");
2937 g_variant_builder_add (&builder, "o", "/bar");
2938 g_variant_builder_add (&builder, "o", "/baz");
2939 value = g_variant_new("(ao^ao^a&o)", &builder, strvector, strvector);
2940 g_variant_iter_init (&tuple, value);
2941 g_variant_iter_next (&tuple, "ao", &array);
2944 while (g_variant_iter_loop (array, "o", &str))
2945 g_assert_cmpstr (str, ==, test_strs[i++]);
2948 g_variant_iter_free (array);
2951 g_variant_iter_init (&tuple, value);
2952 g_variant_iter_next (&tuple, "ao", &array);
2955 while (g_variant_iter_loop (array, "&o", &str))
2956 g_assert_cmpstr (str, ==, test_strs[i++]);
2959 g_variant_iter_free (array);
2961 g_variant_iter_next (&tuple, "^a&o", &strv);
2962 g_variant_iter_next (&tuple, "^ao", &my_strv);
2964 g_assert_cmpstr (strv[0], ==, "/hello");
2965 g_assert_cmpstr (strv[1], ==, "/world");
2966 g_assert (strv[2] == NULL);
2967 g_assert_cmpstr (my_strv[0], ==, "/hello");
2968 g_assert_cmpstr (my_strv[1], ==, "/world");
2969 g_assert (my_strv[2] == NULL);
2971 g_variant_unref (value);
2972 g_strfreev (my_strv);
2977 const gchar *strvector[] = { "i", "ii", "iii", "iv", "v", "vi", NULL };
2978 GVariantBuilder builder;
2987 g_variant_builder_init (&builder, G_VARIANT_TYPE ("aag"));
2988 g_variant_builder_open (&builder, G_VARIANT_TYPE ("ag"));
2989 for (i = 0; i < 6; i++)
2991 g_variant_builder_add (&builder, "g", strvector[i]);
2993 g_variant_builder_add (&builder, "&g", strvector[i]);
2994 g_variant_builder_close (&builder);
2995 g_variant_builder_add (&builder, "^ag", strvector);
2996 g_variant_builder_add (&builder, "^ag", strvector);
2997 value = g_variant_new ("aag", &builder);
2999 g_variant_iter_init (&iter, value);
3000 while (g_variant_iter_loop (&iter, "^ag", &strv))
3001 for (i = 0; i < 6; i++)
3002 g_assert_cmpstr (strv[i], ==, strvector[i]);
3004 g_variant_iter_init (&iter, value);
3005 while (g_variant_iter_loop (&iter, "^a&g", &strv))
3006 for (i = 0; i < 6; i++)
3007 g_assert_cmpstr (strv[i], ==, strvector[i]);
3009 g_variant_iter_init (&iter, value);
3010 while (g_variant_iter_loop (&iter, "ag", &i2))
3015 while (g_variant_iter_loop (i2, "g", &str))
3016 g_assert_cmpstr (str, ==, strvector[i++]);
3020 g_variant_iter_init (&iter, value);
3021 i3 = g_variant_iter_copy (&iter);
3022 while (g_variant_iter_loop (&iter, "@ag", &sub))
3024 gchar *str = g_variant_print (sub, TRUE);
3025 g_assert_cmpstr (str, ==,
3026 "[signature 'i', 'ii', 'iii', 'iv', 'v', 'vi']");
3030 if (do_failed_test ("*NULL has already been returned*"))
3032 g_variant_iter_next_value (&iter);
3037 while (g_variant_iter_loop (i3, "*", &sub))
3039 gchar *str = g_variant_print (sub, TRUE);
3040 g_assert_cmpstr (str, ==,
3041 "[signature 'i', 'ii', 'iii', 'iv', 'v', 'vi']");
3045 g_variant_iter_free (i3);
3047 for (i = 0; i < g_variant_n_children (value); i++)
3051 g_variant_get_child (value, i, "*", &sub);
3053 for (j = 0; j < g_variant_n_children (sub); j++)
3055 const gchar *str = NULL;
3058 g_variant_get_child (sub, j, "&g", &str);
3059 g_assert_cmpstr (str, ==, strvector[j]);
3061 cval = g_variant_get_child_value (sub, j);
3062 g_variant_get (cval, "&g", &str);
3063 g_assert_cmpstr (str, ==, strvector[j]);
3064 g_variant_unref (cval);
3067 g_variant_unref (sub);
3070 g_variant_unref (value);
3089 /* test all 'nothing' */
3090 value = g_variant_new ("(mymbmnmqmimumxmtmhmdmv)",
3093 FALSE, (gint16) 123,
3094 FALSE, (guint16) 123,
3095 FALSE, (gint32) 123,
3096 FALSE, (guint32) 123,
3097 FALSE, (gint64) 123,
3098 FALSE, (guint64) 123,
3100 FALSE, (gdouble) 37.5,
3104 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3118 memset (justs, 1, sizeof justs);
3119 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3131 g_assert (!(justs[0] || justs[1] || justs[2] || justs[3] || justs[4] ||
3132 justs[5] || justs[6] || justs[7] || justs[8] || justs[9]));
3135 memset (justs, 1, sizeof justs);
3136 byteval = i16val = u16val = i32val = u32val = i64val = u64val = hval = 88;
3140 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3141 &justs[0], &byteval,
3152 g_assert (!(justs[0] || justs[1] || justs[2] || justs[3] || justs[4] ||
3153 justs[5] || justs[6] || justs[7] || justs[8] || justs[9]));
3154 g_assert (byteval == '\0' && bval == FALSE);
3155 g_assert (i16val == 0 && u16val == 0 && i32val == 0 &&
3156 u32val == 0 && i64val == 0 && u64val == 0 &&
3157 hval == 0 && dval == 0.0);
3158 g_assert (vval == NULL);
3161 byteval = i16val = u16val = i32val = u32val = i64val = u64val = hval = 88;
3165 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3177 g_assert (byteval == '\0' && bval == FALSE);
3178 g_assert (i16val == 0 && u16val == 0 && i32val == 0 &&
3179 u32val == 0 && i64val == 0 && u64val == 0 &&
3180 hval == 0 && dval == 0.0);
3181 g_assert (vval == NULL);
3183 g_variant_unref (value);
3186 /* test all 'just' */
3187 value = g_variant_new ("(mymbmnmqmimumxmtmhmdmv)",
3191 TRUE, (guint16) 123,
3193 TRUE, (guint32) 123,
3195 TRUE, (guint64) 123,
3197 TRUE, (gdouble) 37.5,
3198 g_variant_new ("()"));
3201 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3215 memset (justs, 0, sizeof justs);
3216 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3228 g_assert (justs[0] && justs[1] && justs[2] && justs[3] && justs[4] &&
3229 justs[5] && justs[6] && justs[7] && justs[8] && justs[9]);
3232 memset (justs, 0, sizeof justs);
3233 byteval = i16val = u16val = i32val = u32val = i64val = u64val = hval = 88;
3237 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3238 &justs[0], &byteval,
3249 g_assert (justs[0] && justs[1] && justs[2] && justs[3] && justs[4] &&
3250 justs[5] && justs[6] && justs[7] && justs[8] && justs[9]);
3251 g_assert (byteval == 'a' && bval == TRUE);
3252 g_assert (i16val == 123 && u16val == 123 && i32val == 123 &&
3253 u32val == 123 && i64val == 123 && u64val == 123 &&
3254 hval == -1 && dval == 37.5);
3255 g_assert (g_variant_is_of_type (vval, G_VARIANT_TYPE_UNIT));
3256 g_variant_unref (vval);
3259 byteval = i16val = u16val = i32val = u32val = i64val = u64val = hval = 88;
3263 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3275 g_assert (byteval == 'a' && bval == TRUE);
3276 g_assert (i16val == 123 && u16val == 123 && i32val == 123 &&
3277 u32val == 123 && i64val == 123 && u64val == 123 &&
3278 hval == -1 && dval == 37.5);
3279 g_assert (g_variant_is_of_type (vval, G_VARIANT_TYPE_UNIT));
3280 g_variant_unref (vval);
3282 g_variant_unref (value);
3285 g_variant_type_info_assert_no_infos ();
3289 hash_get (GVariant *value,
3290 const gchar *format,
3293 const gchar *endptr = NULL;
3297 hash = g_str_has_suffix (format, "#");
3299 va_start (ap, format);
3300 g_variant_get_va (value, format, hash ? &endptr : NULL, &ap);
3304 g_assert (*endptr == '#');
3308 hash_new (const gchar *format,
3311 const gchar *endptr = NULL;
3316 hash = g_str_has_suffix (format, "#");
3318 va_start (ap, format);
3319 value = g_variant_new_va (format, hash ? &endptr : NULL, &ap);
3323 g_assert (*endptr == '#');
3335 value = hash_new ("i", 234);
3336 hash_get (value, "i", &x);
3337 g_assert (x == 234);
3338 g_variant_unref (value);
3341 value = hash_new ("i#", 234);
3342 hash_get (value, "i#", &x);
3343 g_assert (x == 234);
3344 g_variant_unref (value);
3346 g_variant_type_info_assert_no_infos ();
3350 test_builder_memory (void)
3352 GVariantBuilder *hb;
3355 hb = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
3356 g_variant_builder_open (hb, G_VARIANT_TYPE_ARRAY);
3357 g_variant_builder_open (hb, G_VARIANT_TYPE_ARRAY);
3358 g_variant_builder_open (hb, G_VARIANT_TYPE_ARRAY);
3359 g_variant_builder_add (hb, "s", "some value");
3360 g_variant_builder_ref (hb);
3361 g_variant_builder_unref (hb);
3362 g_variant_builder_unref (hb);
3364 hb = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
3365 g_variant_builder_unref (hb);
3367 hb = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
3368 g_variant_builder_clear (hb);
3369 g_variant_builder_unref (hb);
3371 g_variant_builder_init (&sb, G_VARIANT_TYPE_ARRAY);
3372 g_variant_builder_open (&sb, G_VARIANT_TYPE_ARRAY);
3373 g_variant_builder_open (&sb, G_VARIANT_TYPE_ARRAY);
3374 g_variant_builder_add (&sb, "s", "some value");
3375 g_variant_builder_clear (&sb);
3377 g_variant_type_info_assert_no_infos ();
3383 GVariant *items[4096];
3387 table = g_hash_table_new_full (g_variant_hash, g_variant_equal,
3388 (GDestroyNotify ) g_variant_unref,
3391 for (i = 0; i < G_N_ELEMENTS (items); i++)
3397 tree = tree_instance_new (NULL, 0);
3398 items[i] = tree_instance_get_gvariant (tree);
3399 tree_instance_free (tree);
3401 for (j = 0; j < i; j++)
3402 if (g_variant_equal (items[i], items[j]))
3404 g_variant_unref (items[i]);
3408 g_hash_table_insert (table,
3409 g_variant_ref_sink (items[i]),
3410 GINT_TO_POINTER (i));
3413 for (i = 0; i < G_N_ELEMENTS (items); i++)
3417 result = g_hash_table_lookup (table, items[i]);
3418 g_assert_cmpint (GPOINTER_TO_INT (result), ==, i);
3421 g_hash_table_unref (table);
3423 g_variant_type_info_assert_no_infos ();
3429 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
3430 # define native16(x) x, 0
3431 # define swapped16(x) 0, x
3433 # define native16(x) 0, x
3434 # define swapped16(x) x, 0
3436 /* all kinds of of crazy randomised testing already performed on the
3437 * byteswapper in the /gvariant/serialiser/byteswap test and all kinds
3438 * of crazy randomised testing performed against the serialiser
3439 * normalisation functions in the /gvariant/serialiser/fuzz/ tests.
3441 * just test a few simple cases here to make sure they each work
3443 guchar valid_data[] = { 'a', '\0', swapped16(66), 2,
3445 'b', '\0', swapped16(77), 2,
3447 guchar corrupt_data[] = { 'a', '\0', swapped16(66), 2,
3449 'b', '\0', swapped16(77), 2,
3451 GVariant *value, *swapped;
3452 gchar *string, *string2;
3456 value = g_variant_new_from_data (G_VARIANT_TYPE ("a(sn)"),
3457 valid_data, sizeof valid_data, TRUE,
3459 swapped = g_variant_byteswap (value);
3460 g_variant_unref (value);
3461 g_assert (g_variant_get_size (swapped) == 13);
3462 string = g_variant_print (swapped, FALSE);
3463 g_variant_unref (swapped);
3464 g_assert_cmpstr (string, ==, "[('a', 66), ('b', 77)]");
3467 /* untrusted but valid */
3468 value = g_variant_new_from_data (G_VARIANT_TYPE ("a(sn)"),
3469 valid_data, sizeof valid_data, FALSE,
3471 swapped = g_variant_byteswap (value);
3472 g_variant_unref (value);
3473 g_assert (g_variant_get_size (swapped) == 13);
3474 string = g_variant_print (swapped, FALSE);
3475 g_variant_unref (swapped);
3476 g_assert_cmpstr (string, ==, "[('a', 66), ('b', 77)]");
3479 /* untrusted, invalid */
3480 value = g_variant_new_from_data (G_VARIANT_TYPE ("a(sn)"),
3481 corrupt_data, sizeof corrupt_data, FALSE,
3483 string = g_variant_print (value, FALSE);
3484 swapped = g_variant_byteswap (value);
3485 g_variant_unref (value);
3486 g_assert (g_variant_get_size (swapped) == 13);
3487 value = g_variant_byteswap (swapped);
3488 g_variant_unref (swapped);
3489 string2 = g_variant_print (value, FALSE);
3490 g_assert (g_variant_get_size (value) == 13);
3491 g_variant_unref (value);
3492 g_assert_cmpstr (string, ==, string2);
3506 tree = tree_instance_new (NULL, 3);
3507 value = tree_instance_get_gvariant (tree);
3508 tree_instance_free (tree);
3510 pt = g_variant_print (value, TRUE);
3511 p = g_variant_print (value, FALSE);
3513 parsed = g_variant_parse (NULL, pt, NULL, NULL, NULL);
3514 res = g_variant_print (parsed, FALSE);
3515 g_assert_cmpstr (p, ==, res);
3516 g_variant_unref (parsed);
3519 parsed = g_variant_parse (g_variant_get_type (value), p,
3521 res = g_variant_print (parsed, TRUE);
3522 g_assert_cmpstr (pt, ==, res);
3523 g_variant_unref (parsed);
3526 g_variant_unref (value);
3536 for (i = 0; i < 100; i++)
3547 for (i = 0; i < 256; i++)
3550 val = g_variant_new_string (str);
3551 p = g_variant_print (val, FALSE);
3552 g_variant_unref (val);
3554 val = g_variant_parse (NULL, p, NULL, NULL, NULL);
3555 p2 = g_variant_print (val, FALSE);
3557 g_assert_cmpstr (str, ==, g_variant_get_string (val, NULL));
3558 g_assert_cmpstr (p, ==, p2);
3560 g_variant_unref (val);
3565 /* another mini test */
3570 value = g_variant_parse (G_VARIANT_TYPE_INT32, "1 2 3", NULL, &end, NULL);
3571 g_assert_cmpint (g_variant_get_int32 (value), ==, 1);
3572 /* make sure endptr returning works */
3573 g_assert_cmpstr (end, ==, " 2 3");
3574 g_variant_unref (value);
3577 g_variant_type_info_assert_no_infos ();
3581 test_parse_failures (void)
3583 const gchar *test[] = {
3584 "[1, 2,", "6:", "expected value",
3585 "", "0:", "expected value",
3586 "(1, 2,", "6:", "expected value",
3587 "<1", "2:", "expected `>'",
3588 "[]", "0-2:", "unable to infer",
3589 "(,", "1:", "expected value",
3590 "[4,'']", "1-2,3-5:", "common type",
3591 "[4, '', 5]", "1-2,4-6:", "common type",
3592 "['', 4, 5]", "1-3,5-6:", "common type",
3593 "[4, 5, '']", "1-2,7-9:", "common type",
3594 "[[4], [], ['']]", "1-4,10-14:", "common type",
3595 "[[], [4], ['']]", "5-8,10-14:", "common type",
3596 "just", "4:", "expected value",
3597 "nothing", "0-7:", "unable to infer",
3598 "just [4, '']", "6-7,9-11:", "common type",
3599 "[[4,'']]", "2-3,4-6:", "common type",
3600 "([4,''],)", "2-3,4-6:", "common type",
3602 "{}", "0-2:", "unable to infer",
3603 "{[1,2],[3,4]}", "0-13:", "basic types",
3604 "{[1,2]:[3,4]}", "0-13:", "basic types",
3605 "justt", "0-5:", "unknown keyword",
3606 "nothng", "0-6:", "unknown keyword",
3607 "uint33", "0-6:", "unknown keyword",
3608 "@mi just ''", "9-11:", "can not parse as",
3609 "@ai ['']", "5-7:", "can not parse as",
3610 "@(i) ('',)", "6-8:", "can not parse as",
3611 "[[], 5]", "1-3,5-6:", "common type",
3612 "[[5], 5]", "1-4,6-7:", "common type",
3613 "5 5", "2:", "expected end of input",
3614 "[5, [5, '']]", "5-6,8-10:", "common type",
3615 "@i just 5", "3-9:", "can not parse as",
3616 "@i nothing", "3-10:", "can not parse as",
3617 "@i []", "3-5:", "can not parse as",
3618 "@i ()", "3-5:", "can not parse as",
3619 "@ai (4,)", "4-8:", "can not parse as",
3620 "@(i) []", "5-7:", "can not parse as",
3621 "(5 5)", "3:", "expected `,'",
3622 "[5 5]", "3:", "expected `,' or `]'",
3623 "(5, 5 5)", "6:", "expected `,' or `)'",
3624 "[5, 5 5]", "6:", "expected `,' or `]'",
3625 "<@i []>", "4-6:", "can not parse as",
3626 "<[5 5]>", "4:", "expected `,' or `]'",
3627 "{[4,''],5}", "2-3,4-6:", "common type",
3628 "{5,[4,'']}", "4-5,6-8:", "common type",
3629 "@i {1,2}", "3-8:", "can not parse as",
3630 "{@i '', 5}", "4-6:", "can not parse as",
3631 "{5, @i ''}", "7-9:", "can not parse as",
3632 "@ai {}", "4-6:", "can not parse as",
3633 "{@i '': 5}", "4-6:", "can not parse as",
3634 "{5: @i ''}", "7-9:", "can not parse as",
3635 "{<4,5}", "3:", "expected `>'",
3636 "{4,<5}", "5:", "expected `>'",
3637 "{4,5,6}", "4:", "expected `}'",
3638 "{5 5}", "3:", "expected `:' or `,'",
3639 "{4: 5: 6}", "5:", "expected `,' or `}'",
3640 "{4:5,<6:7}", "7:", "expected `>'",
3641 "{4:5,6:<7}", "9:", "expected `>'",
3642 "{4:5,6 7}", "7:", "expected `:'",
3643 "@o 'foo'", "3-8:", "object path",
3644 "@g 'zzz'", "3-8:", "signature",
3645 "@i true", "3-7:", "can not parse as",
3646 "@z 4", "0-2:", "invalid type",
3647 "@a* []", "0-3:", "definite",
3648 "@ai [3 3]", "7:", "expected `,' or `]'",
3649 "18446744073709551616", "0-20:", "too big for any type",
3650 "-18446744073709551616", "0-21:", "too big for any type",
3651 "byte 256", "5-8:", "out of range for type",
3652 "byte -1", "5-7:", "out of range for type",
3653 "int16 32768", "6-11:", "out of range for type",
3654 "int16 -32769", "6-12:", "out of range for type",
3655 "uint16 -1", "7-9:", "out of range for type",
3656 "uint16 65536", "7-12:", "out of range for type",
3657 "2147483648", "0-10:", "out of range for type",
3658 "-2147483649", "0-11:", "out of range for type",
3659 "uint32 -1", "7-9:", "out of range for type",
3660 "uint32 4294967296", "7-17:", "out of range for type",
3661 "@x 9223372036854775808", "3-22:", "out of range for type",
3662 "@x -9223372036854775809", "3-23:", "out of range for type",
3663 "@t -1", "3-5:", "out of range for type",
3664 "@t 18446744073709551616", "3-23:", "too big for any type",
3665 "handle 2147483648", "7-17:", "out of range for type",
3666 "handle -2147483649", "7-18:", "out of range for type",
3667 "1.798e308", "0-9:", "too big for any type",
3668 "37.5a488", "4-5:", "invalid character",
3669 "0x7ffgf", "5-6:", "invalid character",
3670 "07758", "4-5:", "invalid character",
3671 "123a5", "3-4:", "invalid character",
3672 "@ai 123", "4-7:", "can not parse as",
3673 "'\"\\'", "0-4:", "unterminated string",
3674 "'\"\\'\\", "0-5:", "unterminated string",
3675 "boolean 4", "8-9:", "can not parse as",
3676 "int32 true", "6-10:", "can not parse as",
3677 "[double 5, int32 5]", "1-9,11-18:", "common type",
3678 "string 4", "7-8:", "can not parse as"
3682 for (i = 0; i < G_N_ELEMENTS (test); i += 3)
3684 GError *error = NULL;
3687 value = g_variant_parse (NULL, test[i], NULL, NULL, &error);
3688 g_assert (value == NULL);
3690 if (!strstr (error->message, test[i+2]))
3691 g_error ("test %d: Can't find `%s' in `%s'", i / 3,
3692 test[i+2], error->message);
3694 if (!g_str_has_prefix (error->message, test[i+1]))
3695 g_error ("test %d: Expected location `%s' in `%s'", i / 3,
3696 test[i+1], error->message);
3698 g_error_free (error);
3703 test_parse_positional (void)
3706 check_and_free (g_variant_new_parsed ("[('one', 1), (%s, 2),"
3707 " ('three', %i)]", "two", 3),
3708 "[('one', 1), ('two', 2), ('three', 3)]");
3709 value = g_variant_new_parsed ("[('one', 1), (%s, 2),"
3710 " ('three', %u)]", "two", 3);
3711 g_assert (g_variant_is_of_type (value, G_VARIANT_TYPE ("a(su)")));
3712 check_and_free (value, "[('one', 1), ('two', 2), ('three', 3)]");
3713 check_and_free (g_variant_new_parsed ("{%s:%i}", "one", 1), "{'one': 1}");
3715 if (do_failed_test ("*GVariant format string*"))
3717 g_variant_new_parsed ("%z");
3721 if (do_failed_test ("*can not parse as*"))
3723 g_variant_new_parsed ("uint32 %i", 2);
3727 if (do_failed_test ("*expected GVariant of type `i'*"))
3729 g_variant_new_parsed ("%@i", g_variant_new_uint32 (2));
3735 main (int argc, char **argv)
3739 g_test_init (&argc, &argv, NULL);
3741 g_test_add_func ("/gvariant/type", test_gvarianttype);
3742 g_test_add_func ("/gvariant/typeinfo", test_gvarianttypeinfo);
3743 g_test_add_func ("/gvariant/serialiser/maybe", test_maybes);
3744 g_test_add_func ("/gvariant/serialiser/array", test_arrays);
3745 g_test_add_func ("/gvariant/serialiser/tuple", test_tuples);
3746 g_test_add_func ("/gvariant/serialiser/variant", test_variants);
3747 g_test_add_func ("/gvariant/serialiser/strings", test_strings);
3748 g_test_add_func ("/gvariant/serialiser/byteswap", test_byteswaps);
3750 for (i = 1; i <= 20; i += 4)
3754 testname = g_strdup_printf ("/gvariant/serialiser/fuzz/%d%%", i);
3755 g_test_add_data_func (testname, GINT_TO_POINTER (i),
3756 (gpointer) test_fuzzes);
3760 g_test_add_func ("/gvariant/utf8", test_utf8);
3761 g_test_add_func ("/gvariant/containers", test_containers);
3762 g_test_add_func ("/gvariant/format-strings", test_format_strings);
3763 g_test_add_func ("/gvariant/invalid-varargs", test_invalid_varargs);
3764 g_test_add_func ("/gvariant/varargs", test_varargs);
3765 g_test_add_func ("/gvariant/valist", test_valist);
3766 g_test_add_func ("/gvariant/builder-memory", test_builder_memory);
3767 g_test_add_func ("/gvariant/hashing", test_hashing);
3768 g_test_add_func ("/gvariant/byteswap", test_gv_byteswap);
3769 g_test_add_func ("/gvariant/parser", test_parses);
3770 g_test_add_func ("/gvariant/parse-failures", test_parse_failures);
3771 g_test_add_func ("/gvariant/parse-positional", test_parse_positional);
3773 return g_test_run ();