2 * Copyright © 2010 Codethink Limited
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the licence, or (at your option) any later version.
9 * See the included COPYING file for more information.
11 * Author: Ryan Lortie <desrt@desrt.ca>
16 #include <glib/gvariant-internal.h>
17 #include <glib/glib-private.h>
22 #define BASIC "bynqiuxthdsog?"
23 #define N_BASIC (G_N_ELEMENTS (BASIC) - 1)
25 #define INVALIDS "cefjklpwz&@^$"
26 #define N_INVALIDS (G_N_ELEMENTS (INVALIDS) - 1)
28 /* see comment in gvariant-serialiser.c about this madness.
30 * we use this to get testing of non-strictly-aligned GVariant instances
31 * on machines that can tolerate it. it is necessary to support this
32 * because some systems have malloc() that returns non-8-aligned
33 * pointers. it is necessary to have special support in the tests
34 * because on most machines malloc() is 8-aligned.
36 #define ALIGN_BITS (sizeof (struct { char a; union { \
37 guint64 x; void *y; gdouble z; } b; }) - 9)
40 randomly (gdouble prob)
42 return g_test_rand_double_range (0, 1) < prob;
47 append_tuple_type_string (GString *, GString *, gboolean, gint);
49 /* append a random GVariantType to a GString
50 * append a description of the type to another GString
51 * return what the type is
54 append_type_string (GString *string,
59 if (!depth-- || randomly (0.3))
61 gchar b = BASIC[g_test_rand_int_range (0, N_BASIC - definite)];
62 g_string_append_c (string, b);
63 g_string_append_c (description, b);
68 return g_variant_type_copy (G_VARIANT_TYPE_BOOLEAN);
70 return g_variant_type_copy (G_VARIANT_TYPE_BYTE);
72 return g_variant_type_copy (G_VARIANT_TYPE_INT16);
74 return g_variant_type_copy (G_VARIANT_TYPE_UINT16);
76 return g_variant_type_copy (G_VARIANT_TYPE_INT32);
78 return g_variant_type_copy (G_VARIANT_TYPE_UINT32);
80 return g_variant_type_copy (G_VARIANT_TYPE_INT64);
82 return g_variant_type_copy (G_VARIANT_TYPE_UINT64);
84 return g_variant_type_copy (G_VARIANT_TYPE_HANDLE);
86 return g_variant_type_copy (G_VARIANT_TYPE_DOUBLE);
88 return g_variant_type_copy (G_VARIANT_TYPE_STRING);
90 return g_variant_type_copy (G_VARIANT_TYPE_OBJECT_PATH);
92 return g_variant_type_copy (G_VARIANT_TYPE_SIGNATURE);
94 return g_variant_type_copy (G_VARIANT_TYPE_BASIC);
96 g_assert_not_reached ();
101 GVariantType *result;
103 switch (g_test_rand_int_range (0, definite ? 5 : 7))
107 GVariantType *element;
109 g_string_append_c (string, 'a');
110 g_string_append (description, "a of ");
111 element = append_type_string (string, description,
113 result = g_variant_type_new_array (element);
114 g_variant_type_free (element);
117 g_assert (g_variant_type_is_array (result));
122 GVariantType *element;
124 g_string_append_c (string, 'm');
125 g_string_append (description, "m of ");
126 element = append_type_string (string, description,
128 result = g_variant_type_new_maybe (element);
129 g_variant_type_free (element);
132 g_assert (g_variant_type_is_maybe (result));
136 result = append_tuple_type_string (string, description,
139 g_assert (g_variant_type_is_tuple (result));
144 GVariantType *key, *value;
146 g_string_append_c (string, '{');
147 g_string_append (description, "e of [");
148 key = append_type_string (string, description, definite, 0);
149 g_string_append (description, ", ");
150 value = append_type_string (string, description, definite, depth);
151 g_string_append_c (description, ']');
152 g_string_append_c (string, '}');
153 result = g_variant_type_new_dict_entry (key, value);
154 g_variant_type_free (key);
155 g_variant_type_free (value);
158 g_assert (g_variant_type_is_dict_entry (result));
162 g_string_append_c (string, 'v');
163 g_string_append_c (description, 'V');
164 result = g_variant_type_copy (G_VARIANT_TYPE_VARIANT);
165 g_assert (g_variant_type_equal (result, G_VARIANT_TYPE_VARIANT));
169 g_string_append_c (string, '*');
170 g_string_append_c (description, 'S');
171 result = g_variant_type_copy (G_VARIANT_TYPE_ANY);
172 g_assert (g_variant_type_equal (result, G_VARIANT_TYPE_ANY));
176 g_string_append_c (string, 'r');
177 g_string_append_c (description, 'R');
178 result = g_variant_type_copy (G_VARIANT_TYPE_TUPLE);
179 g_assert (g_variant_type_is_tuple (result));
183 g_assert_not_reached ();
190 static GVariantType *
191 append_tuple_type_string (GString *string,
192 GString *description,
196 GVariantType *result, *other_result;
197 GVariantType **types;
201 g_string_append_c (string, '(');
202 g_string_append (description, "t of [");
204 size = g_test_rand_int_range (0, 20);
205 types = g_new (GVariantType *, size + 1);
207 for (i = 0; i < size; i++)
209 types[i] = append_type_string (string, description, definite, depth);
212 g_string_append (description, ", ");
217 g_string_append_c (description, ']');
218 g_string_append_c (string, ')');
220 result = g_variant_type_new_tuple ((gpointer) types, size);
221 other_result = g_variant_type_new_tuple ((gpointer) types, -1);
222 g_assert (g_variant_type_equal (result, other_result));
223 g_variant_type_free (other_result);
224 for (i = 0; i < size; i++)
225 g_variant_type_free (types[i]);
231 /* given a valid type string, make it invalid */
233 invalid_mutation (const gchar *type_string)
235 gboolean have_parens, have_braces;
237 /* it's valid, so '(' implies ')' and same for '{' and '}' */
238 have_parens = strchr (type_string, '(') != NULL;
239 have_braces = strchr (type_string, '{') != NULL;
241 if (have_parens && have_braces && randomly (0.3))
243 /* swap a paren and a brace */
249 new = g_strdup (type_string);
259 /* count number of parens/braces */
260 while ((pp = strchr (pp + 1, p))) np++;
261 while ((bp = strchr (bp + 1, b))) nb++;
263 /* randomly pick one of each */
264 np = g_test_rand_int_range (0, np) + 1;
265 nb = g_test_rand_int_range (0, nb) + 1;
269 while (np--) pp = strchr (pp + 1, p);
270 while (nb--) bp = strchr (bp + 1, b);
273 g_assert (*bp == b && *pp == p);
280 if ((have_parens || have_braces) && randomly (0.3))
282 /* drop a paren/brace */
289 if (randomly (0.5)) p = '('; else p = ')';
291 if (randomly (0.5)) p = '{'; else p = '}';
293 new = g_strdup (type_string);
297 while ((pp = strchr (pp + 1, p))) np++;
298 np = g_test_rand_int_range (0, np) + 1;
300 while (np--) pp = strchr (pp + 1, p);
312 /* else, perform a random mutation at a random point */
320 /* insert a paren/brace */
322 if (randomly (0.5)) p = '('; else p = ')';
324 if (randomly (0.5)) p = '{'; else p = '}';
326 else if (randomly (0.5))
329 p = INVALIDS[g_test_rand_int_range (0, N_INVALIDS)];
338 length = strlen (type_string);
339 new = g_malloc (length + 2);
340 n = g_test_rand_int_range (0, length);
341 memcpy (new, type_string, n);
343 memcpy (new + n + 1, type_string + n, length - n);
344 new[length + 1] = '\0';
350 /* describe a type using the same language as is generated
351 * while generating the type with append_type_string
354 describe_type (const GVariantType *type)
358 if (g_variant_type_is_container (type))
360 g_assert (!g_variant_type_is_basic (type));
362 if (g_variant_type_is_array (type))
364 gchar *subtype = describe_type (g_variant_type_element (type));
365 result = g_strdup_printf ("a of %s", subtype);
368 else if (g_variant_type_is_maybe (type))
370 gchar *subtype = describe_type (g_variant_type_element (type));
371 result = g_strdup_printf ("m of %s", subtype);
374 else if (g_variant_type_is_tuple (type))
376 if (!g_variant_type_equal (type, G_VARIANT_TYPE_TUPLE))
378 const GVariantType *sub;
383 string = g_string_new ("t of [");
385 length = g_variant_type_n_items (type);
386 sub = g_variant_type_first (type);
387 for (i = 0; i < length; i++)
389 gchar *subtype = describe_type (sub);
390 g_string_append (string, subtype);
393 if ((sub = g_variant_type_next (sub)))
394 g_string_append (string, ", ");
396 g_assert (sub == NULL);
397 g_string_append_c (string, ']');
399 result = g_string_free (string, FALSE);
402 result = g_strdup ("R");
404 else if (g_variant_type_is_dict_entry (type))
406 gchar *key, *value, *key2, *value2;
408 key = describe_type (g_variant_type_key (type));
409 value = describe_type (g_variant_type_value (type));
410 key2 = describe_type (g_variant_type_first (type));
411 value2 = describe_type (
412 g_variant_type_next (g_variant_type_first (type)));
413 g_assert (g_variant_type_next (g_variant_type_next (
414 g_variant_type_first (type))) == NULL);
415 g_assert_cmpstr (key, ==, key2);
416 g_assert_cmpstr (value, ==, value2);
417 result = g_strjoin ("", "e of [", key, ", ", value, "]", NULL);
423 else if (g_variant_type_equal (type, G_VARIANT_TYPE_VARIANT))
425 result = g_strdup ("V");
428 g_assert_not_reached ();
432 if (g_variant_type_is_definite (type))
434 g_assert (g_variant_type_is_basic (type));
436 if (g_variant_type_equal (type, G_VARIANT_TYPE_BOOLEAN))
437 result = g_strdup ("b");
438 else if (g_variant_type_equal (type, G_VARIANT_TYPE_BYTE))
439 result = g_strdup ("y");
440 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT16))
441 result = g_strdup ("n");
442 else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT16))
443 result = g_strdup ("q");
444 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32))
445 result = g_strdup ("i");
446 else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT32))
447 result = g_strdup ("u");
448 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT64))
449 result = g_strdup ("x");
450 else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT64))
451 result = g_strdup ("t");
452 else if (g_variant_type_equal (type, G_VARIANT_TYPE_HANDLE))
453 result = g_strdup ("h");
454 else if (g_variant_type_equal (type, G_VARIANT_TYPE_DOUBLE))
455 result = g_strdup ("d");
456 else if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING))
457 result = g_strdup ("s");
458 else if (g_variant_type_equal (type, G_VARIANT_TYPE_OBJECT_PATH))
459 result = g_strdup ("o");
460 else if (g_variant_type_equal (type, G_VARIANT_TYPE_SIGNATURE))
461 result = g_strdup ("g");
463 g_assert_not_reached ();
467 if (g_variant_type_equal (type, G_VARIANT_TYPE_ANY))
469 result = g_strdup ("S");
471 else if (g_variant_type_equal (type, G_VARIANT_TYPE_BASIC))
473 result = g_strdup ("?");
476 g_assert_not_reached ();
483 /* given a type string, replace one of the indefinite type characters in
484 * it with a matching type (possibly the same type).
487 generate_subtype (const gchar *type_string)
489 GVariantType *replacement;
490 GString *result, *junk;
491 gint length, n = 0, l;
493 result = g_string_new (NULL);
494 junk = g_string_new (NULL);
496 /* count the number of indefinite type characters */
497 for (length = 0; type_string[length]; length++)
498 n += type_string[length] == 'r' ||
499 type_string[length] == '?' ||
500 type_string[length] == '*';
501 /* length now is strlen (type_string) */
503 /* pick one at random to replace */
504 n = g_test_rand_int_range (0, n) + 1;
508 while (n--) l += strcspn (type_string + l + 1, "r?*") + 1;
509 g_assert (type_string[l] == 'r' ||
510 type_string[l] == '?' ||
511 type_string[l] == '*');
513 /* store up to that point in a GString */
514 g_string_append_len (result, type_string, l);
516 /* then store the replacement in the GString */
517 if (type_string[l] == 'r')
518 replacement = append_tuple_type_string (result, junk, FALSE, 3);
520 else if (type_string[l] == '?')
521 replacement = append_type_string (result, junk, FALSE, 0);
523 else if (type_string[l] == '*')
524 replacement = append_type_string (result, junk, FALSE, 3);
527 g_assert_not_reached ();
529 /* ensure the replacement has the proper type */
530 g_assert (g_variant_type_is_subtype_of (replacement,
531 (gpointer) &type_string[l]));
533 /* store the rest from the original type string */
534 g_string_append (result, type_string + l + 1);
536 g_variant_type_free (replacement);
537 g_string_free (junk, TRUE);
539 return g_string_free (result, FALSE);
544 const GVariantType *type;
545 struct typestack *parent;
548 /* given an indefinite type string, replace one of the indefinite
549 * characters in it with a matching type and ensure that the result is a
550 * subtype of the original. repeat.
553 subtype_check (const gchar *type_string,
554 struct typestack *parent_ts)
556 struct typestack ts, *node;
560 subtype = generate_subtype (type_string);
562 ts.type = G_VARIANT_TYPE (subtype);
563 ts.parent = parent_ts;
565 for (node = &ts; node; node = node->parent)
567 /* this type should be a subtype of each parent type */
568 g_assert (g_variant_type_is_subtype_of (ts.type, node->type));
570 /* it should only be a supertype when it is exactly equal */
571 g_assert (g_variant_type_is_subtype_of (node->type, ts.type) ==
572 g_variant_type_equal (ts.type, node->type));
577 if (!g_variant_type_is_definite (ts.type) && depth < 5)
579 /* the type is still indefinite and we haven't repeated too many
580 * times. go once more.
583 subtype_check (subtype, &ts);
590 test_gvarianttype (void)
594 for (i = 0; i < 2000; i++)
596 GString *type_string, *description;
597 GVariantType *type, *other_type;
598 const GVariantType *ctype;
602 type_string = g_string_new (NULL);
603 description = g_string_new (NULL);
605 /* generate a random type, its type string and a description
607 * exercises type constructor functions and g_variant_type_copy()
609 type = append_type_string (type_string, description, FALSE, 6);
611 /* convert the type string to a type and ensure that it is equal
612 * to the one produced with the type constructor routines
614 ctype = G_VARIANT_TYPE (type_string->str);
615 g_assert (g_variant_type_equal (ctype, type));
616 g_assert (g_variant_type_hash (ctype) == g_variant_type_hash (type));
617 g_assert (g_variant_type_is_subtype_of (ctype, type));
618 g_assert (g_variant_type_is_subtype_of (type, ctype));
620 /* check if the type is indefinite */
621 if (!g_variant_type_is_definite (type))
623 struct typestack ts = { type, NULL };
625 /* if it is indefinite, then replace one of the indefinite
626 * characters with a matching type and ensure that the result
627 * is a subtype of the original type. repeat.
629 subtype_check (type_string->str, &ts);
632 /* ensure that no indefinite characters appear */
633 g_assert (strcspn (type_string->str, "r?*") == type_string->len);
636 /* describe the type.
638 * exercises the type iterator interface
640 desc = describe_type (type);
642 /* make sure the description matches */
643 g_assert_cmpstr (desc, ==, description->str);
646 /* make an invalid mutation to the type and make sure the type
647 * validation routines catch it */
648 invalid = invalid_mutation (type_string->str);
649 g_assert (g_variant_type_string_is_valid (type_string->str));
650 g_assert (!g_variant_type_string_is_valid (invalid));
653 /* concatenate another type to the type string and ensure that
654 * the result is recognised as being invalid
656 other_type = append_type_string (type_string, description, FALSE, 2);
658 g_string_free (description, TRUE);
659 g_string_free (type_string, TRUE);
660 g_variant_type_free (other_type);
661 g_variant_type_free (type);
665 #define ALIGNED(x, y) (((x + (y - 1)) / y) * y)
667 /* do our own calculation of the fixed_size and alignment of a type
668 * using a simple algorithm to make sure the "fancy" one in the
669 * implementation is correct.
672 calculate_type_info (const GVariantType *type,
676 if (g_variant_type_is_array (type) ||
677 g_variant_type_is_maybe (type))
679 calculate_type_info (g_variant_type_element (type), NULL, alignment);
684 else if (g_variant_type_is_tuple (type) ||
685 g_variant_type_is_dict_entry (type))
687 if (g_variant_type_n_items (type))
689 const GVariantType *sub;
698 sub = g_variant_type_first (type);
704 calculate_type_info (sub, &this_fs, &this_al);
706 al = MAX (al, this_al);
716 size = ALIGNED (size, this_al);
720 while ((sub = g_variant_type_next (sub)));
722 size = ALIGNED (size, al);
743 if (g_variant_type_equal (type, G_VARIANT_TYPE_BOOLEAN) ||
744 g_variant_type_equal (type, G_VARIANT_TYPE_BYTE))
749 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT16) ||
750 g_variant_type_equal (type, G_VARIANT_TYPE_UINT16))
755 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32) ||
756 g_variant_type_equal (type, G_VARIANT_TYPE_UINT32) ||
757 g_variant_type_equal (type, G_VARIANT_TYPE_HANDLE))
762 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT64) ||
763 g_variant_type_equal (type, G_VARIANT_TYPE_UINT64) ||
764 g_variant_type_equal (type, G_VARIANT_TYPE_DOUBLE))
768 else if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING) ||
769 g_variant_type_equal (type, G_VARIANT_TYPE_OBJECT_PATH) ||
770 g_variant_type_equal (type, G_VARIANT_TYPE_SIGNATURE))
775 else if (g_variant_type_equal (type, G_VARIANT_TYPE_VARIANT))
781 g_assert_not_reached ();
791 /* same as the describe_type() function above, but iterates over
792 * typeinfo instead of types.
795 describe_info (GVariantTypeInfo *info)
799 switch (g_variant_type_info_get_type_char (info))
801 case G_VARIANT_TYPE_INFO_CHAR_MAYBE:
805 element = describe_info (g_variant_type_info_element (info));
806 result = g_strdup_printf ("m of %s", element);
811 case G_VARIANT_TYPE_INFO_CHAR_ARRAY:
815 element = describe_info (g_variant_type_info_element (info));
816 result = g_strdup_printf ("a of %s", element);
821 case G_VARIANT_TYPE_INFO_CHAR_TUPLE:
823 const gchar *sep = "";
828 string = g_string_new ("t of [");
829 length = g_variant_type_info_n_members (info);
831 for (i = 0; i < length; i++)
833 const GVariantMemberInfo *minfo;
836 g_string_append (string, sep);
839 minfo = g_variant_type_info_member_info (info, i);
840 subtype = describe_info (minfo->type_info);
841 g_string_append (string, subtype);
845 g_string_append_c (string, ']');
847 result = g_string_free (string, FALSE);
851 case G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY:
853 const GVariantMemberInfo *keyinfo, *valueinfo;
856 g_assert_cmpint (g_variant_type_info_n_members (info), ==, 2);
857 keyinfo = g_variant_type_info_member_info (info, 0);
858 valueinfo = g_variant_type_info_member_info (info, 1);
859 key = describe_info (keyinfo->type_info);
860 value = describe_info (valueinfo->type_info);
861 result = g_strjoin ("", "e of [", key, ", ", value, "]", NULL);
867 case G_VARIANT_TYPE_INFO_CHAR_VARIANT:
868 result = g_strdup ("V");
872 result = g_strdup (g_variant_type_info_get_type_string (info));
873 g_assert_cmpint (strlen (result), ==, 1);
880 /* check that the O(1) method of calculating offsets meshes with the
881 * results of simple iteration.
884 check_offsets (GVariantTypeInfo *info,
885 const GVariantType *type)
890 length = g_variant_type_info_n_members (info);
891 g_assert_cmpint (length, ==, g_variant_type_n_items (type));
893 /* the 'flavour' is the low order bits of the ending point of
894 * variable-size items in the tuple. this lets us test that the type
895 * info is correct for various starting alignments.
897 for (flavour = 0; flavour < 8; flavour++)
899 const GVariantType *subtype;
900 gsize last_offset_index;
905 subtype = g_variant_type_first (type);
906 last_offset_index = -1;
910 /* go through the tuple, keeping track of our position */
911 for (i = 0; i < length; i++)
916 calculate_type_info (subtype, &fixed_size, &alignment);
918 position = ALIGNED (position, alignment);
920 /* compare our current aligned position (ie: the start of this
921 * item) to the start offset that would be calculated if we
925 const GVariantMemberInfo *member;
928 member = g_variant_type_info_member_info (info, i);
929 g_assert_cmpint (member->i, ==, last_offset_index);
931 /* do the calculation using the typeinfo */
937 /* did we reach the same spot? */
938 g_assert_cmpint (start, ==, position);
943 /* fixed size. add that size. */
944 position += fixed_size;
948 /* variable size. do the flavouring. */
949 while ((position & 0x7) != flavour)
952 /* and store the offset, just like it would be in the
955 last_offset = position;
960 subtype = g_variant_type_next (subtype);
963 /* make sure we used up exactly all the types */
964 g_assert (subtype == NULL);
969 test_gvarianttypeinfo (void)
973 for (i = 0; i < 2000; i++)
975 GString *type_string, *description;
976 gsize fixed_size1, fixed_size2;
977 guint alignment1, alignment2;
978 GVariantTypeInfo *info;
982 type_string = g_string_new (NULL);
983 description = g_string_new (NULL);
986 type = append_type_string (type_string, description, TRUE, 6);
988 /* create a typeinfo for it */
989 info = g_variant_type_info_get (type);
991 /* make sure the typeinfo has the right type string */
992 g_assert_cmpstr (g_variant_type_info_get_type_string (info), ==,
995 /* calculate the alignment and fixed size, compare to the
996 * typeinfo's calculations
998 calculate_type_info (type, &fixed_size1, &alignment1);
999 g_variant_type_info_query (info, &alignment2, &fixed_size2);
1000 g_assert_cmpint (fixed_size1, ==, fixed_size2);
1001 g_assert_cmpint (alignment1, ==, alignment2 + 1);
1003 /* test the iteration functions over typeinfo structures by
1004 * "describing" the typeinfo and verifying equality.
1006 desc = describe_info (info);
1007 g_assert_cmpstr (desc, ==, description->str);
1009 /* do extra checks for containers */
1010 if (g_variant_type_is_array (type) ||
1011 g_variant_type_is_maybe (type))
1013 const GVariantType *element;
1017 element = g_variant_type_element (type);
1018 calculate_type_info (element, &efs1, &ea1);
1019 g_variant_type_info_query_element (info, &ea2, &efs2);
1020 g_assert_cmpint (efs1, ==, efs2);
1021 g_assert_cmpint (ea1, ==, ea2 + 1);
1023 g_assert_cmpint (ea1, ==, alignment1);
1024 g_assert_cmpint (0, ==, fixed_size1);
1026 else if (g_variant_type_is_tuple (type) ||
1027 g_variant_type_is_dict_entry (type))
1029 /* make sure the "magic constants" are working */
1030 check_offsets (info, type);
1033 g_string_free (type_string, TRUE);
1034 g_string_free (description, TRUE);
1035 g_variant_type_info_unref (info);
1036 g_variant_type_free (type);
1040 g_variant_type_info_assert_no_infos ();
1043 #define MAX_FIXED_MULTIPLIER 256
1044 #define MAX_INSTANCE_SIZE 1024
1045 #define MAX_ARRAY_CHILDREN 128
1046 #define MAX_TUPLE_CHILDREN 128
1048 /* this function generates a random type such that all characteristics
1049 * that are "interesting" to the serialiser are tested.
1051 * this basically means:
1052 * - test different alignments
1053 * - test variable sized items and fixed sized items
1054 * - test different fixed sizes
1057 random_type_string (void)
1059 const guchar base_types[] = "ynix";
1062 base_type = base_types[g_test_rand_int_range (0, 4)];
1064 if (g_test_rand_bit ())
1065 /* construct a fixed-sized type */
1067 char type_string[MAX_FIXED_MULTIPLIER];
1071 multiplier = g_test_rand_int_range (1, sizeof type_string - 1);
1073 type_string[i++] = '(';
1074 while (multiplier--)
1075 type_string[i++] = base_type;
1076 type_string[i++] = ')';
1078 return g_strndup (type_string, i);
1081 /* construct a variable-sized type */
1083 char type_string[2] = { 'a', base_type };
1085 return g_strndup (type_string, 2);
1091 GVariantTypeInfo *type_info;
1094 gboolean is_fixed_sized;
1098 #define INSTANCE_MAGIC 1287582829
1102 static RandomInstance *
1103 random_instance (GVariantTypeInfo *type_info)
1105 RandomInstance *instance;
1107 instance = g_slice_new (RandomInstance);
1109 if (type_info == NULL)
1111 gchar *str = random_type_string ();
1112 instance->type_info = g_variant_type_info_get (G_VARIANT_TYPE (str));
1116 instance->type_info = g_variant_type_info_ref (type_info);
1118 instance->seed = g_test_rand_int ();
1120 g_variant_type_info_query (instance->type_info,
1121 &instance->alignment,
1124 instance->is_fixed_sized = instance->size != 0;
1126 if (!instance->is_fixed_sized)
1127 instance->size = g_test_rand_int_range (0, MAX_INSTANCE_SIZE);
1129 instance->magic = INSTANCE_MAGIC;
1135 random_instance_free (RandomInstance *instance)
1137 g_variant_type_info_unref (instance->type_info);
1138 g_slice_free (RandomInstance, instance);
1142 append_instance_size (RandomInstance *instance,
1145 *offset += (-*offset) & instance->alignment;
1146 *offset += instance->size;
1150 random_instance_write (RandomInstance *instance,
1156 g_assert_cmpint ((gsize) buffer & ALIGN_BITS & instance->alignment, ==, 0);
1158 rand = g_rand_new_with_seed (instance->seed);
1159 for (i = 0; i < instance->size; i++)
1160 buffer[i] = g_rand_int (rand);
1165 append_instance_data (RandomInstance *instance,
1168 while (((gsize) *buffer) & instance->alignment)
1169 *(*buffer)++ = '\0';
1171 random_instance_write (instance, *buffer);
1172 *buffer += instance->size;
1176 random_instance_assert (RandomInstance *instance,
1183 g_assert_cmpint ((gsize) buffer & ALIGN_BITS & instance->alignment, ==, 0);
1184 g_assert_cmpint (size, ==, instance->size);
1186 rand = g_rand_new_with_seed (instance->seed);
1187 for (i = 0; i < instance->size; i++)
1189 guchar byte = g_rand_int (rand);
1191 g_assert (buffer[i] == byte);
1195 return i == instance->size;
1199 random_instance_check (RandomInstance *instance,
1206 g_assert_cmpint ((gsize) buffer & ALIGN_BITS & instance->alignment, ==, 0);
1208 if (size != instance->size)
1211 rand = g_rand_new_with_seed (instance->seed);
1212 for (i = 0; i < instance->size; i++)
1213 if (buffer[i] != (guchar) g_rand_int (rand))
1217 return i == instance->size;
1221 random_instance_filler (GVariantSerialised *serialised,
1224 RandomInstance *instance = data;
1226 g_assert (instance->magic == INSTANCE_MAGIC);
1228 if (serialised->type_info == NULL)
1229 serialised->type_info = instance->type_info;
1231 if (serialised->size == 0)
1232 serialised->size = instance->size;
1234 g_assert (serialised->type_info == instance->type_info);
1235 g_assert (serialised->size == instance->size);
1237 if (serialised->data)
1238 random_instance_write (instance, serialised->data);
1242 calculate_offset_size (gsize body_size,
1248 if (body_size + n_offsets <= G_MAXUINT8)
1251 if (body_size + 2 * n_offsets <= G_MAXUINT16)
1254 if (body_size + 4 * n_offsets <= G_MAXUINT32)
1257 /* the test case won't generate anything bigger */
1258 g_assert_not_reached ();
1262 flavoured_malloc (gsize size, gsize flavour)
1264 g_assert (flavour < 8);
1269 return ((gchar *) g_malloc (size + flavour)) + flavour;
1273 flavoured_free (gpointer data,
1278 g_free (((gchar *) data) - flavour);
1282 align_malloc (gsize size)
1286 #ifdef HAVE_POSIX_MEMALIGN
1287 if (posix_memalign (&mem, 8, size))
1288 g_error ("posix_memalign failed");
1290 /* NOTE: there may be platforms that lack posix_memalign() and also
1291 * have malloc() that returns non-8-aligned. if so, we need to try
1294 mem = malloc (size);
1301 align_free (gpointer mem)
1307 append_offset (guchar **offset_ptr,
1313 guchar bytes[sizeof (gsize)];
1317 tmpvalue.integer = GSIZE_TO_LE (offset);
1318 memcpy (*offset_ptr, tmpvalue.bytes, offset_size);
1319 *offset_ptr += offset_size;
1323 prepend_offset (guchar **offset_ptr,
1329 guchar bytes[sizeof (gsize)];
1333 *offset_ptr -= offset_size;
1334 tmpvalue.integer = GSIZE_TO_LE (offset);
1335 memcpy (*offset_ptr, tmpvalue.bytes, offset_size);
1341 GVariantTypeInfo *type_info;
1342 RandomInstance *instance;
1346 instance = random_instance (NULL);
1349 const gchar *element;
1352 element = g_variant_type_info_get_type_string (instance->type_info);
1353 tmp = g_strdup_printf ("m%s", element);
1354 type_info = g_variant_type_info_get (G_VARIANT_TYPE (tmp));
1358 needed_size = g_variant_serialiser_needed_size (type_info,
1359 random_instance_filler,
1361 g_assert_cmpint (needed_size, ==, 0);
1363 needed_size = g_variant_serialiser_needed_size (type_info,
1364 random_instance_filler,
1365 (gpointer *) &instance, 1);
1367 if (instance->is_fixed_sized)
1368 g_assert_cmpint (needed_size, ==, instance->size);
1370 g_assert_cmpint (needed_size, ==, instance->size + 1);
1375 ptr = data = align_malloc (needed_size);
1376 append_instance_data (instance, &ptr);
1378 if (!instance->is_fixed_sized)
1381 g_assert_cmpint (ptr - data, ==, needed_size);
1388 alignment = (instance->alignment & ALIGN_BITS) + 1;
1390 for (flavour = 0; flavour < 8; flavour += alignment)
1392 GVariantSerialised serialised;
1393 GVariantSerialised child;
1395 serialised.type_info = type_info;
1396 serialised.data = flavoured_malloc (needed_size, flavour);
1397 serialised.size = needed_size;
1399 g_variant_serialiser_serialise (serialised,
1400 random_instance_filler,
1401 (gpointer *) &instance, 1);
1402 child = g_variant_serialised_get_child (serialised, 0);
1403 g_assert (child.type_info == instance->type_info);
1404 random_instance_assert (instance, child.data, child.size);
1405 g_variant_type_info_unref (child.type_info);
1406 flavoured_free (serialised.data, flavour);
1410 g_variant_type_info_unref (type_info);
1411 random_instance_free (instance);
1420 for (i = 0; i < 1000; i++)
1423 g_variant_type_info_assert_no_infos ();
1429 GVariantTypeInfo *element_info;
1430 GVariantTypeInfo *array_info;
1431 RandomInstance **instances;
1438 gchar *element_type, *array_type;
1440 element_type = random_type_string ();
1441 array_type = g_strdup_printf ("a%s", element_type);
1443 element_info = g_variant_type_info_get (G_VARIANT_TYPE (element_type));
1444 array_info = g_variant_type_info_get (G_VARIANT_TYPE (array_type));
1445 g_assert (g_variant_type_info_element (array_info) == element_info);
1447 g_free (element_type);
1448 g_free (array_type);
1454 n_children = g_test_rand_int_range (0, MAX_ARRAY_CHILDREN);
1455 instances = g_new (RandomInstance *, n_children);
1456 for (i = 0; i < n_children; i++)
1457 instances[i] = random_instance (element_info);
1460 needed_size = g_variant_serialiser_needed_size (array_info,
1461 random_instance_filler,
1462 (gpointer *) instances,
1466 gsize element_fixed_size;
1467 gsize body_size = 0;
1470 for (i = 0; i < n_children; i++)
1471 append_instance_size (instances[i], &body_size);
1473 g_variant_type_info_query (element_info, NULL, &element_fixed_size);
1475 if (!element_fixed_size)
1477 offset_size = calculate_offset_size (body_size, n_children);
1479 if (offset_size == 0)
1485 g_assert_cmpint (needed_size, ==, body_size + n_children * offset_size);
1489 guchar *offset_ptr, *body_ptr;
1492 body_ptr = data = align_malloc (needed_size);
1493 offset_ptr = body_ptr + needed_size - offset_size * n_children;
1495 for (i = 0; i < n_children; i++)
1497 append_instance_data (instances[i], &body_ptr);
1498 append_offset (&offset_ptr, body_ptr - data, offset_size);
1501 g_assert (body_ptr == data + needed_size - offset_size * n_children);
1502 g_assert (offset_ptr == data + needed_size);
1510 g_variant_type_info_query (array_info, &alignment, NULL);
1511 alignment = (alignment & ALIGN_BITS) + 1;
1513 for (flavour = 0; flavour < 8; flavour += alignment)
1515 GVariantSerialised serialised;
1517 serialised.type_info = array_info;
1518 serialised.data = flavoured_malloc (needed_size, flavour);
1519 serialised.size = needed_size;
1521 g_variant_serialiser_serialise (serialised, random_instance_filler,
1522 (gpointer *) instances, n_children);
1524 if (serialised.size)
1525 g_assert (memcmp (serialised.data, data, serialised.size) == 0);
1527 g_assert (g_variant_serialised_n_children (serialised) == n_children);
1529 for (i = 0; i < n_children; i++)
1531 GVariantSerialised child;
1533 child = g_variant_serialised_get_child (serialised, i);
1534 g_assert (child.type_info == instances[i]->type_info);
1535 random_instance_assert (instances[i], child.data, child.size);
1536 g_variant_type_info_unref (child.type_info);
1539 flavoured_free (serialised.data, flavour);
1546 for (i = 0; i < n_children; i++)
1547 random_instance_free (instances[i]);
1551 g_variant_type_info_unref (element_info);
1552 g_variant_type_info_unref (array_info);
1561 for (i = 0; i < 100; i++)
1564 g_variant_type_info_assert_no_infos ();
1570 GVariantTypeInfo *type_info;
1571 RandomInstance **instances;
1572 gboolean fixed_size;
1579 n_children = g_test_rand_int_range (0, MAX_TUPLE_CHILDREN);
1580 instances = g_new (RandomInstance *, n_children);
1583 GString *type_string;
1589 type_string = g_string_new ("(");
1590 for (i = 0; i < n_children; i++)
1594 instances[i] = random_instance (NULL);
1596 alignment |= instances[i]->alignment;
1597 if (!instances[i]->is_fixed_sized)
1600 str = g_variant_type_info_get_type_string (instances[i]->type_info);
1601 g_string_append (type_string, str);
1603 g_string_append_c (type_string, ')');
1605 type_info = g_variant_type_info_get (G_VARIANT_TYPE (type_string->str));
1606 g_string_free (type_string, TRUE);
1609 needed_size = g_variant_serialiser_needed_size (type_info,
1610 random_instance_filler,
1611 (gpointer *) instances,
1614 gsize body_size = 0;
1618 for (i = 0; i < n_children; i++)
1620 append_instance_size (instances[i], &body_size);
1622 if (i != n_children - 1 && !instances[i]->is_fixed_sized)
1628 body_size += (-body_size) & alignment;
1630 g_assert ((body_size == 0) == (n_children == 0));
1631 if (n_children == 0)
1635 offset_size = calculate_offset_size (body_size, offsets);
1636 g_assert_cmpint (needed_size, ==, body_size + offsets * offset_size);
1644 body_ptr = data = align_malloc (needed_size);
1645 ofs_ptr = body_ptr + needed_size;
1647 for (i = 0; i < n_children; i++)
1649 append_instance_data (instances[i], &body_ptr);
1651 if (i != n_children - 1 && !instances[i]->is_fixed_sized)
1652 prepend_offset (&ofs_ptr, body_ptr - data, offset_size);
1657 while (((gsize) body_ptr) & alignment)
1660 g_assert ((body_ptr == data) == (n_children == 0));
1661 if (n_children == 0)
1667 g_assert (body_ptr == ofs_ptr);
1674 alignment = (alignment & ALIGN_BITS) + 1;
1676 for (flavour = 0; flavour < 8; flavour += alignment)
1678 GVariantSerialised serialised;
1680 serialised.type_info = type_info;
1681 serialised.data = flavoured_malloc (needed_size, flavour);
1682 serialised.size = needed_size;
1684 g_variant_serialiser_serialise (serialised, random_instance_filler,
1685 (gpointer *) instances, n_children);
1687 if (serialised.size)
1688 g_assert (memcmp (serialised.data, data, serialised.size) == 0);
1690 g_assert (g_variant_serialised_n_children (serialised) == n_children);
1692 for (i = 0; i < n_children; i++)
1694 GVariantSerialised child;
1696 child = g_variant_serialised_get_child (serialised, i);
1697 g_assert (child.type_info == instances[i]->type_info);
1698 random_instance_assert (instances[i], child.data, child.size);
1699 g_variant_type_info_unref (child.type_info);
1702 flavoured_free (serialised.data, flavour);
1709 for (i = 0; i < n_children; i++)
1710 random_instance_free (instances[i]);
1714 g_variant_type_info_unref (type_info);
1723 for (i = 0; i < 100; i++)
1726 g_variant_type_info_assert_no_infos ();
1732 GVariantTypeInfo *type_info;
1733 RandomInstance *instance;
1734 const gchar *type_string;
1739 type_info = g_variant_type_info_get (G_VARIANT_TYPE_VARIANT);
1740 instance = random_instance (NULL);
1742 type_string = g_variant_type_info_get_type_string (instance->type_info);
1743 len = strlen (type_string);
1745 needed_size = g_variant_serialiser_needed_size (type_info,
1746 random_instance_filler,
1747 (gpointer *) &instance, 1);
1749 g_assert_cmpint (needed_size, ==, instance->size + 1 + len);
1754 ptr = data = align_malloc (needed_size);
1755 append_instance_data (instance, &ptr);
1757 memcpy (ptr, type_string, len);
1760 g_assert (data + needed_size == ptr);
1767 /* variants are always 8-aligned */
1768 alignment = ALIGN_BITS + 1;
1770 for (flavour = 0; flavour < 8; flavour += alignment)
1772 GVariantSerialised serialised;
1773 GVariantSerialised child;
1775 serialised.type_info = type_info;
1776 serialised.data = flavoured_malloc (needed_size, flavour);
1777 serialised.size = needed_size;
1779 g_variant_serialiser_serialise (serialised, random_instance_filler,
1780 (gpointer *) &instance, 1);
1782 if (serialised.size)
1783 g_assert (memcmp (serialised.data, data, serialised.size) == 0);
1785 g_assert (g_variant_serialised_n_children (serialised) == 1);
1787 child = g_variant_serialised_get_child (serialised, 0);
1788 g_assert (child.type_info == instance->type_info);
1789 random_instance_check (instance, child.data, child.size);
1791 g_variant_type_info_unref (child.type_info);
1792 flavoured_free (serialised.data, flavour);
1796 g_variant_type_info_unref (type_info);
1797 random_instance_free (instance);
1802 test_variants (void)
1806 for (i = 0; i < 100; i++)
1809 g_variant_type_info_assert_no_infos ();
1822 #define is_objpath is_string | 2
1823 #define is_sig is_string | 4
1825 { is_nval, 0, NULL },
1826 { is_nval, 13, "hello\xffworld!" },
1827 { is_string, 13, "hello world!" },
1828 { is_nval, 13, "hello world\0" },
1829 { is_nval, 13, "hello\0world!" },
1830 { is_nval, 12, "hello world!" },
1831 { is_nval, 13, "hello world!\xff" },
1833 { is_objpath, 2, "/" },
1834 { is_objpath, 3, "/a" },
1835 { is_string, 3, "//" },
1836 { is_objpath, 11, "/some/path" },
1837 { is_string, 12, "/some/path/" },
1838 { is_nval, 11, "/some\0path" },
1839 { is_string, 11, "/some\\path" },
1840 { is_string, 12, "/some//path" },
1841 { is_string, 12, "/some-/path" },
1845 { is_sig, 5, "(si)" },
1846 { is_string, 4, "(si" },
1847 { is_string, 2, "*" },
1848 { is_sig, 3, "ai" },
1849 { is_string, 3, "mi" },
1850 { is_string, 2, "r" },
1851 { is_sig, 15, "(yyy{sv}ssiai)" },
1852 { is_string, 16, "(yyy{yv}ssiai))" },
1853 { is_string, 15, "(yyy{vv}ssiai)" },
1854 { is_string, 15, "(yyy{sv)ssiai}" }
1858 for (i = 0; i < G_N_ELEMENTS (test_cases); i++)
1862 flags = g_variant_serialiser_is_string (test_cases[i].data,
1866 flags |= g_variant_serialiser_is_object_path (test_cases[i].data,
1870 flags |= g_variant_serialiser_is_signature (test_cases[i].data,
1874 g_assert (flags == test_cases[i].flags);
1878 typedef struct _TreeInstance TreeInstance;
1879 struct _TreeInstance
1881 GVariantTypeInfo *info;
1883 TreeInstance **children;
1894 static GVariantType *
1895 make_random_definite_type (int depth)
1897 GString *description;
1898 GString *type_string;
1901 description = g_string_new (NULL);
1902 type_string = g_string_new (NULL);
1903 type = append_type_string (type_string, description, TRUE, depth);
1904 g_string_free (description, TRUE);
1905 g_string_free (type_string, TRUE);
1911 make_random_string (gchar *string,
1913 const GVariantType *type)
1917 /* create strings that are valid signature strings */
1918 #define good_chars "bynqiuxthdsog"
1920 for (i = 0; i < size - 1; i++)
1921 string[i] = good_chars[g_test_rand_int_range (0, strlen (good_chars))];
1924 /* in case we need an object path, prefix a '/' */
1925 if (*g_variant_type_peek_string (type) == 'o')
1931 static TreeInstance *
1932 tree_instance_new (const GVariantType *type,
1935 const GVariantType *child_type = NULL;
1936 GVariantType *mytype = NULL;
1937 TreeInstance *instance;
1938 gboolean is_tuple_type;
1941 type = mytype = make_random_definite_type (depth);
1943 instance = g_slice_new (TreeInstance);
1944 instance->info = g_variant_type_info_get (type);
1945 instance->children = NULL;
1946 instance->n_children = 0;
1947 instance->data_size = 0;
1949 is_tuple_type = FALSE;
1951 switch (*g_variant_type_peek_string (type))
1953 case G_VARIANT_TYPE_INFO_CHAR_MAYBE:
1954 instance->n_children = g_test_rand_int_range (0, 2);
1955 child_type = g_variant_type_element (type);
1958 case G_VARIANT_TYPE_INFO_CHAR_ARRAY:
1959 instance->n_children = g_test_rand_int_range (0, MAX_ARRAY_CHILDREN);
1960 child_type = g_variant_type_element (type);
1963 case G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY:
1964 case G_VARIANT_TYPE_INFO_CHAR_TUPLE:
1965 instance->n_children = g_variant_type_n_items (type);
1966 child_type = g_variant_type_first (type);
1967 is_tuple_type = TRUE;
1970 case G_VARIANT_TYPE_INFO_CHAR_VARIANT:
1971 instance->n_children = 1;
1976 instance->data.integer = g_test_rand_int_range (0, 2);
1977 instance->data_size = 1;
1981 instance->data.integer = g_test_rand_int ();
1982 instance->data_size = 1;
1986 instance->data.integer = g_test_rand_int ();
1987 instance->data_size = 2;
1990 case 'i': case 'u': case 'h':
1991 instance->data.integer = g_test_rand_int ();
1992 instance->data_size = 4;
1996 instance->data.integer = g_test_rand_int ();
1997 instance->data.integer <<= 32;
1998 instance->data.integer |= (guint32) g_test_rand_int ();
1999 instance->data_size = 8;
2003 instance->data.floating = g_test_rand_double ();
2004 instance->data_size = 8;
2007 case 's': case 'o': case 'g':
2008 instance->data_size = g_test_rand_int_range (10, 200);
2009 make_random_string (instance->data.string, instance->data_size, type);
2013 if (instance->data_size == 0)
2014 /* no data -> it is a container */
2018 instance->children = g_new (TreeInstance *, instance->n_children);
2020 for (i = 0; i < instance->n_children; i++)
2022 instance->children[i] = tree_instance_new (child_type, depth - 1);
2025 child_type = g_variant_type_next (child_type);
2028 g_assert (!is_tuple_type || child_type == NULL);
2031 g_variant_type_free (mytype);
2037 tree_instance_free (TreeInstance *instance)
2041 g_variant_type_info_unref (instance->info);
2042 for (i = 0; i < instance->n_children; i++)
2043 tree_instance_free (instance->children[i]);
2044 g_free (instance->children);
2045 g_slice_free (TreeInstance, instance);
2048 static gboolean i_am_writing_byteswapped;
2051 tree_filler (GVariantSerialised *serialised,
2054 TreeInstance *instance = data;
2056 if (serialised->type_info == NULL)
2057 serialised->type_info = instance->info;
2059 if (instance->data_size == 0)
2060 /* is a container */
2062 if (serialised->size == 0)
2064 g_variant_serialiser_needed_size (instance->info, tree_filler,
2065 (gpointer *) instance->children,
2066 instance->n_children);
2068 if (serialised->data)
2069 g_variant_serialiser_serialise (*serialised, tree_filler,
2070 (gpointer *) instance->children,
2071 instance->n_children);
2076 if (serialised->size == 0)
2077 serialised->size = instance->data_size;
2079 if (serialised->data)
2081 switch (instance->data_size)
2084 *serialised->data = instance->data.integer;
2089 guint16 value = instance->data.integer;
2091 if (i_am_writing_byteswapped)
2092 value = GUINT16_SWAP_LE_BE (value);
2094 *(guint16 *) serialised->data = value;
2100 guint32 value = instance->data.integer;
2102 if (i_am_writing_byteswapped)
2103 value = GUINT32_SWAP_LE_BE (value);
2105 *(guint32 *) serialised->data = value;
2111 guint64 value = instance->data.integer;
2113 if (i_am_writing_byteswapped)
2114 value = GUINT64_SWAP_LE_BE (value);
2116 *(guint64 *) serialised->data = value;
2121 memcpy (serialised->data,
2122 instance->data.string,
2123 instance->data_size);
2131 check_tree (TreeInstance *instance,
2132 GVariantSerialised serialised)
2134 if (instance->info != serialised.type_info)
2137 if (instance->data_size == 0)
2138 /* is a container */
2142 if (g_variant_serialised_n_children (serialised) !=
2143 instance->n_children)
2146 for (i = 0; i < instance->n_children; i++)
2148 GVariantSerialised child;
2149 gpointer data = NULL;
2152 child = g_variant_serialised_get_child (serialised, i);
2153 if (child.size && child.data == NULL)
2154 child.data = data = g_malloc0 (child.size);
2155 ok = check_tree (instance->children[i], child);
2156 g_variant_type_info_unref (child.type_info);
2168 switch (instance->data_size)
2171 g_assert (serialised.size == 1);
2172 return *(guint8 *) serialised.data ==
2173 (guint8) instance->data.integer;
2176 g_assert (serialised.size == 2);
2177 return *(guint16 *) serialised.data ==
2178 (guint16) instance->data.integer;
2181 g_assert (serialised.size == 4);
2182 return *(guint32 *) serialised.data ==
2183 (guint32) instance->data.integer;
2186 g_assert (serialised.size == 8);
2187 return *(guint64 *) serialised.data ==
2188 (guint64) instance->data.integer;
2191 if (serialised.size != instance->data_size)
2194 return memcmp (serialised.data,
2195 instance->data.string,
2196 instance->data_size) == 0;
2202 serialise_tree (TreeInstance *tree,
2203 GVariantSerialised *serialised)
2205 GVariantSerialised empty = {0, };
2207 *serialised = empty;
2208 tree_filler (serialised, tree);
2209 serialised->data = g_malloc (serialised->size);
2210 tree_filler (serialised, tree);
2214 test_byteswap (void)
2216 GVariantSerialised one, two;
2219 tree = tree_instance_new (NULL, 3);
2220 serialise_tree (tree, &one);
2222 i_am_writing_byteswapped = TRUE;
2223 serialise_tree (tree, &two);
2224 i_am_writing_byteswapped = FALSE;
2226 g_variant_serialised_byteswap (two);
2228 g_assert_cmpint (one.size, ==, two.size);
2229 g_assert (memcmp (one.data, two.data, one.size) == 0);
2231 tree_instance_free (tree);
2237 test_byteswaps (void)
2241 for (i = 0; i < 200; i++)
2244 g_variant_type_info_assert_no_infos ();
2248 test_fuzz (gdouble *fuzziness)
2250 GVariantSerialised serialised;
2253 /* make an instance */
2254 tree = tree_instance_new (NULL, 3);
2257 serialise_tree (tree, &serialised);
2259 g_assert (g_variant_serialised_is_normal (serialised));
2260 g_assert (check_tree (tree, serialised));
2262 if (serialised.size)
2264 gboolean fuzzed = FALSE;
2271 for (i = 0; i < serialised.size; i++)
2272 if (randomly (*fuzziness))
2274 serialised.data[i] += g_test_rand_int_range (1, 256);
2279 /* at least one byte in the serialised data has changed.
2281 * this means that at least one of the following is true:
2283 * - the serialised data now represents a different value:
2284 * check_tree() will return FALSE
2286 * - the serialised data is in non-normal form:
2287 * g_variant_serialiser_is_normal() will return FALSE
2289 * we always do both checks to increase exposure of the serialiser
2292 a = g_variant_serialised_is_normal (serialised);
2293 b = check_tree (tree, serialised);
2295 g_assert (!a || !b);
2298 tree_instance_free (tree);
2299 g_free (serialised.data);
2304 test_fuzzes (gpointer data)
2309 fuzziness = GPOINTER_TO_INT (data) / 100.;
2311 for (i = 0; i < 200; i++)
2312 test_fuzz (&fuzziness);
2314 g_variant_type_info_assert_no_infos ();
2318 tree_instance_get_gvariant (TreeInstance *tree)
2320 const GVariantType *type;
2323 type = (GVariantType *) g_variant_type_info_get_type_string (tree->info);
2325 switch (g_variant_type_info_get_type_char (tree->info))
2327 case G_VARIANT_TYPE_INFO_CHAR_MAYBE:
2329 const GVariantType *child_type;
2332 if (tree->n_children)
2333 child = tree_instance_get_gvariant (tree->children[0]);
2337 child_type = g_variant_type_element (type);
2339 if (child != NULL && randomly (0.5))
2342 result = g_variant_new_maybe (child_type, child);
2346 case G_VARIANT_TYPE_INFO_CHAR_ARRAY:
2348 const GVariantType *child_type;
2349 GVariant **children;
2352 children = g_new (GVariant *, tree->n_children);
2353 for (i = 0; i < tree->n_children; i++)
2354 children[i] = tree_instance_get_gvariant (tree->children[i]);
2356 child_type = g_variant_type_element (type);
2358 if (i > 0 && randomly (0.5))
2361 result = g_variant_new_array (child_type, children, tree->n_children);
2366 case G_VARIANT_TYPE_INFO_CHAR_TUPLE:
2368 GVariant **children;
2371 children = g_new (GVariant *, tree->n_children);
2372 for (i = 0; i < tree->n_children; i++)
2373 children[i] = tree_instance_get_gvariant (tree->children[i]);
2375 result = g_variant_new_tuple (children, tree->n_children);
2380 case G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY:
2382 GVariant *key, *val;
2384 g_assert (tree->n_children == 2);
2386 key = tree_instance_get_gvariant (tree->children[0]);
2387 val = tree_instance_get_gvariant (tree->children[1]);
2389 result = g_variant_new_dict_entry (key, val);
2393 case G_VARIANT_TYPE_INFO_CHAR_VARIANT:
2397 g_assert (tree->n_children == 1);
2399 value = tree_instance_get_gvariant (tree->children[0]);
2400 result = g_variant_new_variant (value);
2405 result = g_variant_new_boolean (tree->data.integer > 0);
2409 result = g_variant_new_byte (tree->data.integer);
2413 result = g_variant_new_int16 (tree->data.integer);
2417 result = g_variant_new_uint16 (tree->data.integer);
2421 result = g_variant_new_int32 (tree->data.integer);
2425 result = g_variant_new_uint32 (tree->data.integer);
2429 result = g_variant_new_int64 (tree->data.integer);
2433 result = g_variant_new_uint64 (tree->data.integer);
2437 result = g_variant_new_handle (tree->data.integer);
2441 result = g_variant_new_double (tree->data.floating);
2445 result = g_variant_new_string (tree->data.string);
2449 result = g_variant_new_object_path (tree->data.string);
2453 result = g_variant_new_signature (tree->data.string);
2457 g_assert_not_reached ();
2464 create_random_gvariant (guint depth)
2469 tree = tree_instance_new (NULL, depth);
2470 value = g_variant_take_ref (tree_instance_get_gvariant (tree));
2471 tree_instance_free (tree);
2477 tree_instance_check_gvariant (TreeInstance *tree,
2480 const GVariantType *type;
2482 type = (GVariantType *) g_variant_type_info_get_type_string (tree->info);
2483 g_assert (g_variant_is_of_type (value, type));
2485 switch (g_variant_type_info_get_type_char (tree->info))
2487 case G_VARIANT_TYPE_INFO_CHAR_MAYBE:
2492 child = g_variant_get_maybe (value);
2494 if (child != NULL && tree->n_children == 1)
2495 equal = tree_instance_check_gvariant (tree->children[0], child);
2496 else if (child == NULL && tree->n_children == 0)
2502 g_variant_unref (child);
2508 case G_VARIANT_TYPE_INFO_CHAR_ARRAY:
2509 case G_VARIANT_TYPE_INFO_CHAR_TUPLE:
2510 case G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY:
2514 if (g_variant_n_children (value) != tree->n_children)
2517 for (i = 0; i < tree->n_children; i++)
2522 child = g_variant_get_child_value (value, i);
2523 equal = tree_instance_check_gvariant (tree->children[i], child);
2524 g_variant_unref (child);
2534 case G_VARIANT_TYPE_INFO_CHAR_VARIANT:
2536 const gchar *str1, *str2;
2540 child = g_variant_get_variant (value);
2541 str1 = g_variant_get_type_string (child);
2542 str2 = g_variant_type_info_get_type_string (tree->children[0]->info);
2543 /* GVariant only keeps one copy of type strings around */
2544 equal = str1 == str2 &&
2545 tree_instance_check_gvariant (tree->children[0], child);
2547 g_variant_unref (child);
2554 return g_variant_get_boolean (value) == tree->data.integer;
2557 return g_variant_get_byte (value) == (guchar) tree->data.integer;
2560 return g_variant_get_int16 (value) == (gint16) tree->data.integer;
2563 return g_variant_get_uint16 (value) == (guint16) tree->data.integer;
2566 return g_variant_get_int32 (value) == (gint32) tree->data.integer;
2569 return g_variant_get_uint32 (value) == (guint32) tree->data.integer;
2572 return g_variant_get_int64 (value) == (gint64) tree->data.integer;
2575 return g_variant_get_uint64 (value) == (guint64) tree->data.integer;
2578 return g_variant_get_handle (value) == (gint32) tree->data.integer;
2582 gdouble floating = g_variant_get_double (value);
2584 return memcmp (&floating, &tree->data.floating, sizeof floating) == 0;
2590 return strcmp (g_variant_get_string (value, NULL),
2591 tree->data.string) == 0;
2594 g_assert_not_reached ();
2599 tree_instance_build_gvariant (TreeInstance *tree,
2600 GVariantBuilder *builder,
2603 const GVariantType *type;
2605 type = (GVariantType *) g_variant_type_info_get_type_string (tree->info);
2607 if (g_variant_type_is_container (type))
2611 /* force GVariantBuilder to guess the type half the time */
2612 if (guess_ok && randomly (0.5))
2614 if (g_variant_type_is_array (type) && tree->n_children)
2615 type = G_VARIANT_TYPE_ARRAY;
2617 if (g_variant_type_is_maybe (type) && tree->n_children)
2618 type = G_VARIANT_TYPE_MAYBE;
2620 if (g_variant_type_is_tuple (type))
2621 type = G_VARIANT_TYPE_TUPLE;
2623 if (g_variant_type_is_dict_entry (type))
2624 type = G_VARIANT_TYPE_DICT_ENTRY;
2629 g_variant_builder_open (builder, type);
2631 for (i = 0; i < tree->n_children; i++)
2632 tree_instance_build_gvariant (tree->children[i], builder, guess_ok);
2634 g_variant_builder_close (builder);
2637 g_variant_builder_add_value (builder, tree_instance_get_gvariant (tree));
2642 tree_instance_check_iter (TreeInstance *tree,
2647 value = g_variant_iter_next_value (iter);
2649 if (g_variant_is_container (value))
2653 iter = g_variant_iter_new (value);
2654 g_variant_unref (value);
2656 if (g_variant_iter_n_children (iter) != tree->n_children)
2658 g_variant_iter_free (iter);
2662 for (i = 0; i < tree->n_children; i++)
2663 if (!tree_instance_check_iter (tree->children[i], iter))
2665 g_variant_iter_free (iter);
2669 g_assert (g_variant_iter_next_value (iter) == NULL);
2670 g_variant_iter_free (iter);
2679 equal = tree_instance_check_gvariant (tree, value);
2680 g_variant_unref (value);
2687 test_container (void)
2693 tree = tree_instance_new (NULL, 3);
2694 value = g_variant_ref_sink (tree_instance_get_gvariant (tree));
2696 s1 = g_variant_print (value, TRUE);
2697 g_assert (tree_instance_check_gvariant (tree, value));
2699 g_variant_get_data (value);
2701 s2 = g_variant_print (value, TRUE);
2702 g_assert (tree_instance_check_gvariant (tree, value));
2704 g_assert_cmpstr (s1, ==, s2);
2706 if (g_variant_is_container (value))
2708 GVariantBuilder builder;
2714 g_variant_builder_init (&builder, G_VARIANT_TYPE_VARIANT);
2715 tree_instance_build_gvariant (tree, &builder, TRUE);
2716 built = g_variant_builder_end (&builder);
2717 g_variant_ref_sink (built);
2718 g_variant_get_data (built);
2719 val = g_variant_get_variant (built);
2721 s3 = g_variant_print (val, TRUE);
2722 g_assert_cmpstr (s1, ==, s3);
2724 g_variant_iter_init (&iter, built);
2725 g_assert (tree_instance_check_iter (tree, &iter));
2726 g_assert (g_variant_iter_next_value (&iter) == NULL);
2728 g_variant_unref (built);
2729 g_variant_unref (val);
2733 tree_instance_free (tree);
2734 g_variant_unref (value);
2742 /* Test some different methods of creating strings */
2745 v = g_variant_new_string ("foo");
2746 g_assert_cmpstr (g_variant_get_string (v, NULL), ==, "foo");
2747 g_variant_unref (v);
2750 v = g_variant_new_take_string (g_strdup ("foo"));
2751 g_assert_cmpstr (g_variant_get_string (v, NULL), ==, "foo");
2752 g_variant_unref (v);
2754 v = g_variant_new_printf ("%s %d", "foo", 123);
2755 g_assert_cmpstr (g_variant_get_string (v, NULL), ==, "foo 123");
2756 g_variant_unref (v);
2762 const gchar invalid[] = "hello\xffworld";
2765 /* ensure that the test data is not valid utf8... */
2766 g_assert (!g_utf8_validate (invalid, -1, NULL));
2768 /* load the data untrusted */
2769 value = g_variant_new_from_data (G_VARIANT_TYPE_STRING,
2770 invalid, sizeof invalid,
2773 /* ensure that the problem is caught and we get valid UTF-8 */
2774 g_assert (g_utf8_validate (g_variant_get_string (value, NULL), -1, NULL));
2775 g_variant_unref (value);
2778 /* now load it trusted */
2779 value = g_variant_new_from_data (G_VARIANT_TYPE_STRING,
2780 invalid, sizeof invalid,
2783 /* ensure we get the invalid data (ie: make sure that time wasn't
2784 * wasted on validating data that was marked as trusted)
2786 g_assert (g_variant_get_string (value, NULL) == invalid);
2787 g_variant_unref (value);
2791 test_containers (void)
2795 for (i = 0; i < 100; i++)
2800 g_variant_type_info_assert_no_infos ();
2804 test_format_strings (void)
2809 g_assert (g_variant_format_string_scan ("i", NULL, &end) && *end == '\0');
2810 g_assert (g_variant_format_string_scan ("@i", NULL, &end) && *end == '\0');
2811 g_assert (g_variant_format_string_scan ("@ii", NULL, &end) && *end == 'i');
2812 g_assert (g_variant_format_string_scan ("^a&s", NULL, &end) && *end == '\0');
2813 g_assert (g_variant_format_string_scan ("(^as)", NULL, &end) &&
2815 g_assert (!g_variant_format_string_scan ("(^s)", NULL, &end));
2816 g_assert (!g_variant_format_string_scan ("(^a)", NULL, &end));
2817 g_assert (!g_variant_format_string_scan ("(z)", NULL, &end));
2818 g_assert (!g_variant_format_string_scan ("az", NULL, &end));
2819 g_assert (!g_variant_format_string_scan ("{**}", NULL, &end));
2820 g_assert (!g_variant_format_string_scan ("{@**}", NULL, &end));
2821 g_assert (g_variant_format_string_scan ("{@y*}", NULL, &end) &&
2823 g_assert (g_variant_format_string_scan ("{yv}", NULL, &end) &&
2825 g_assert (!g_variant_format_string_scan ("{&?v}", NULL, &end));
2826 g_assert (g_variant_format_string_scan ("{@?v}", NULL, &end) &&
2828 g_assert (!g_variant_format_string_scan ("{&@sv}", NULL, &end));
2829 g_assert (!g_variant_format_string_scan ("{@&sv}", NULL, &end));
2830 g_assert (g_variant_format_string_scan ("{&sv}", NULL, &end) &&
2832 g_assert (!g_variant_format_string_scan ("{vv}", NULL, &end));
2833 g_assert (!g_variant_format_string_scan ("{y}", NULL, &end));
2834 g_assert (!g_variant_format_string_scan ("{yyy}", NULL, &end));
2835 g_assert (!g_variant_format_string_scan ("{ya}", NULL, &end));
2836 g_assert (g_variant_format_string_scan ("&s", NULL, &end) && *end == '\0');
2837 g_assert (!g_variant_format_string_scan ("&as", NULL, &end));
2838 g_assert (!g_variant_format_string_scan ("@z", NULL, &end));
2839 g_assert (!g_variant_format_string_scan ("az", NULL, &end));
2840 g_assert (!g_variant_format_string_scan ("a&s", NULL, &end));
2842 type = g_variant_format_string_scan_type ("mm(@xy^a&s*?@?)", NULL, &end);
2843 g_assert (type && *end == '\0');
2844 g_assert (g_variant_type_equal (type, G_VARIANT_TYPE ("mm(xyas*?\?)")));
2845 g_variant_type_free (type);
2847 type = g_variant_format_string_scan_type ("mm(@xy^a&*?@?)", NULL, NULL);
2848 g_assert (type == NULL);
2852 do_failed_test (const char *test,
2853 const gchar *pattern)
2855 g_test_trap_subprocess (test, 1000000, 0);
2856 g_test_trap_assert_failed ();
2857 g_test_trap_assert_stderr (pattern);
2861 test_invalid_varargs (void)
2866 if (!g_test_undefined ())
2869 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
2870 "*GVariant format string*");
2871 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
2872 "*valid_format_string*");
2873 value = g_variant_new ("z");
2874 g_test_assert_expected_messages ();
2875 g_assert (value == NULL);
2877 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
2878 "*valid GVariant format string as a prefix*");
2879 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
2880 "*valid_format_string*");
2881 value = g_variant_new_va ("z", &end, NULL);
2882 g_test_assert_expected_messages ();
2883 g_assert (value == NULL);
2885 value = g_variant_new ("y", 'a');
2886 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
2887 "*type of 'q' but * has a type of 'y'*");
2888 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
2889 "*valid_format_string*");
2890 g_variant_get (value, "q");
2891 g_test_assert_expected_messages ();
2892 g_variant_unref (value);
2896 check_and_free (GVariant *value,
2899 gchar *valstr = g_variant_print (value, FALSE);
2900 g_assert_cmpstr (str, ==, valstr);
2901 g_variant_unref (value);
2906 test_varargs_empty_array (void)
2908 g_variant_new ("(a{s*})", NULL);
2910 g_assert_not_reached ();
2917 GVariantBuilder array;
2919 g_variant_builder_init (&array, G_VARIANT_TYPE_ARRAY);
2920 g_variant_builder_add_parsed (&array, "{'size', <(%i, %i)> }", 800, 600);
2921 g_variant_builder_add (&array, "{sv}", "title",
2922 g_variant_new_string ("Test case"));
2923 g_variant_builder_add_value (&array,
2924 g_variant_new_dict_entry (g_variant_new_string ("temperature"),
2925 g_variant_new_variant (
2926 g_variant_new_double (37.5))));
2927 check_and_free (g_variant_new ("(ma{sv}m(a{sv})ma{sv}ii)",
2928 NULL, FALSE, NULL, &array, 7777, 8888),
2929 "(nothing, nothing, {'size': <(800, 600)>, "
2930 "'title': <'Test case'>, "
2931 "'temperature': <37.5>}, "
2934 check_and_free (g_variant_new ("(imimimmimmimmi)",
2941 "(123, nothing, 123, nothing, just nothing, 123)");
2943 check_and_free (g_variant_new ("(ybnixd)",
2944 'a', 1, 22, 33, (guint64) 44, 5.5),
2945 "(0x61, true, 22, 33, 44, 5.5)");
2947 check_and_free (g_variant_new ("(@y?*rv)",
2948 g_variant_new ("y", 'a'),
2949 g_variant_new ("y", 'b'),
2950 g_variant_new ("y", 'c'),
2951 g_variant_new ("(y)", 'd'),
2952 g_variant_new ("y", 'e')),
2953 "(0x61, 0x62, 0x63, (0x64,), <byte 0x65>)");
2957 GVariantBuilder array;
2964 g_variant_builder_init (&array, G_VARIANT_TYPE_ARRAY);
2965 for (i = 0; i < 100; i++)
2967 number = g_strdup_printf ("%d", i);
2968 g_variant_builder_add (&array, "s", number);
2972 value = g_variant_builder_end (&array);
2973 g_variant_iter_init (&iter, value);
2976 while (g_variant_iter_loop (&iter, "s", &number))
2978 gchar *check = g_strdup_printf ("%d", i++);
2979 g_assert_cmpstr (number, ==, check);
2982 g_assert (number == NULL);
2983 g_assert (i == 100);
2985 g_variant_unref (value);
2987 g_variant_builder_init (&array, G_VARIANT_TYPE_ARRAY);
2988 for (i = 0; i < 100; i++)
2989 g_variant_builder_add (&array, "mi", i % 2 == 0, i);
2990 value = g_variant_builder_end (&array);
2993 g_variant_iter_init (&iter, value);
2994 while (g_variant_iter_loop (&iter, "mi", NULL, &val))
2995 g_assert (val == i++ || val == 0);
2996 g_assert (i == 100);
2999 g_variant_iter_init (&iter, value);
3000 while (g_variant_iter_loop (&iter, "mi", &just, &val))
3007 g_assert (val == this);
3012 g_assert (val == 0);
3015 g_assert (i == 100);
3017 g_variant_unref (value);
3021 const gchar *strvector[] = {"/hello", "/world", NULL};
3022 const gchar *test_strs[] = {"/foo", "/bar", "/baz" };
3023 GVariantBuilder builder;
3024 GVariantIter *array;
3032 g_variant_builder_init (&builder, G_VARIANT_TYPE ("as"));
3033 g_variant_builder_add (&builder, "s", "/foo");
3034 g_variant_builder_add (&builder, "s", "/bar");
3035 g_variant_builder_add (&builder, "s", "/baz");
3036 value = g_variant_new("(as^as^a&s)", &builder, strvector, strvector);
3037 g_variant_iter_init (&tuple, value);
3038 g_variant_iter_next (&tuple, "as", &array);
3041 while (g_variant_iter_loop (array, "s", &str))
3042 g_assert_cmpstr (str, ==, test_strs[i++]);
3045 g_variant_iter_free (array);
3048 g_variant_iter_init (&tuple, value);
3049 g_variant_iter_next (&tuple, "as", &array);
3052 while (g_variant_iter_loop (array, "&s", &str))
3053 g_assert_cmpstr (str, ==, test_strs[i++]);
3056 g_variant_iter_free (array);
3058 g_variant_iter_next (&tuple, "^a&s", &strv);
3059 g_variant_iter_next (&tuple, "^as", &my_strv);
3061 g_assert_cmpstr (strv[0], ==, "/hello");
3062 g_assert_cmpstr (strv[1], ==, "/world");
3063 g_assert (strv[2] == NULL);
3064 g_assert_cmpstr (my_strv[0], ==, "/hello");
3065 g_assert_cmpstr (my_strv[1], ==, "/world");
3066 g_assert (my_strv[2] == NULL);
3068 g_variant_unref (value);
3069 g_strfreev (my_strv);
3074 const gchar *strvector[] = {"/hello", "/world", NULL};
3075 const gchar *test_strs[] = {"/foo", "/bar", "/baz" };
3076 GVariantBuilder builder;
3077 GVariantIter *array;
3085 g_variant_builder_init (&builder, G_VARIANT_TYPE_OBJECT_PATH_ARRAY);
3086 g_variant_builder_add (&builder, "o", "/foo");
3087 g_variant_builder_add (&builder, "o", "/bar");
3088 g_variant_builder_add (&builder, "o", "/baz");
3089 value = g_variant_new("(ao^ao^a&o)", &builder, strvector, strvector);
3090 g_variant_iter_init (&tuple, value);
3091 g_variant_iter_next (&tuple, "ao", &array);
3094 while (g_variant_iter_loop (array, "o", &str))
3095 g_assert_cmpstr (str, ==, test_strs[i++]);
3098 g_variant_iter_free (array);
3101 g_variant_iter_init (&tuple, value);
3102 g_variant_iter_next (&tuple, "ao", &array);
3105 while (g_variant_iter_loop (array, "&o", &str))
3106 g_assert_cmpstr (str, ==, test_strs[i++]);
3109 g_variant_iter_free (array);
3111 g_variant_iter_next (&tuple, "^a&o", &strv);
3112 g_variant_iter_next (&tuple, "^ao", &my_strv);
3114 g_assert_cmpstr (strv[0], ==, "/hello");
3115 g_assert_cmpstr (strv[1], ==, "/world");
3116 g_assert (strv[2] == NULL);
3117 g_assert_cmpstr (my_strv[0], ==, "/hello");
3118 g_assert_cmpstr (my_strv[1], ==, "/world");
3119 g_assert (my_strv[2] == NULL);
3121 g_variant_unref (value);
3122 g_strfreev (my_strv);
3127 const gchar *strvector[] = { "i", "ii", "iii", "iv", "v", "vi", NULL };
3128 GVariantBuilder builder;
3137 g_variant_builder_init (&builder, G_VARIANT_TYPE ("aas"));
3138 g_variant_builder_open (&builder, G_VARIANT_TYPE ("as"));
3139 for (i = 0; i < 6; i++)
3141 g_variant_builder_add (&builder, "s", strvector[i]);
3143 g_variant_builder_add (&builder, "&s", strvector[i]);
3144 g_variant_builder_close (&builder);
3145 g_variant_builder_add (&builder, "^as", strvector);
3146 g_variant_builder_add (&builder, "^as", strvector);
3147 value = g_variant_new ("aas", &builder);
3149 g_variant_iter_init (&iter, value);
3150 while (g_variant_iter_loop (&iter, "^as", &strv))
3151 for (i = 0; i < 6; i++)
3152 g_assert_cmpstr (strv[i], ==, strvector[i]);
3154 g_variant_iter_init (&iter, value);
3155 while (g_variant_iter_loop (&iter, "^a&s", &strv))
3156 for (i = 0; i < 6; i++)
3157 g_assert_cmpstr (strv[i], ==, strvector[i]);
3159 g_variant_iter_init (&iter, value);
3160 while (g_variant_iter_loop (&iter, "as", &i2))
3165 while (g_variant_iter_loop (i2, "s", &str))
3166 g_assert_cmpstr (str, ==, strvector[i++]);
3170 g_variant_iter_init (&iter, value);
3171 i3 = g_variant_iter_copy (&iter);
3172 while (g_variant_iter_loop (&iter, "@as", &sub))
3174 gchar *str = g_variant_print (sub, TRUE);
3175 g_assert_cmpstr (str, ==,
3176 "['i', 'ii', 'iii', 'iv', 'v', 'vi']");
3180 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
3181 "*NULL has already been returned*");
3182 g_variant_iter_next_value (&iter);
3183 g_test_assert_expected_messages ();
3185 while (g_variant_iter_loop (i3, "*", &sub))
3187 gchar *str = g_variant_print (sub, TRUE);
3188 g_assert_cmpstr (str, ==,
3189 "['i', 'ii', 'iii', 'iv', 'v', 'vi']");
3193 g_variant_iter_free (i3);
3195 for (i = 0; i < g_variant_n_children (value); i++)
3199 g_variant_get_child (value, i, "*", &sub);
3201 for (j = 0; j < g_variant_n_children (sub); j++)
3203 const gchar *str = NULL;
3206 g_variant_get_child (sub, j, "&s", &str);
3207 g_assert_cmpstr (str, ==, strvector[j]);
3209 cval = g_variant_get_child_value (sub, j);
3210 g_variant_get (cval, "&s", &str);
3211 g_assert_cmpstr (str, ==, strvector[j]);
3212 g_variant_unref (cval);
3215 g_variant_unref (sub);
3218 g_variant_unref (value);
3237 /* test all 'nothing' */
3238 value = g_variant_new ("(mymbmnmqmimumxmtmhmdmv)",
3241 FALSE, (gint16) 123,
3242 FALSE, (guint16) 123,
3243 FALSE, (gint32) 123,
3244 FALSE, (guint32) 123,
3245 FALSE, (gint64) 123,
3246 FALSE, (guint64) 123,
3248 FALSE, (gdouble) 37.5,
3252 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3266 memset (justs, 1, sizeof justs);
3267 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3279 g_assert (!(justs[0] || justs[1] || justs[2] || justs[3] || justs[4] ||
3280 justs[5] || justs[6] || justs[7] || justs[8] || justs[9]));
3283 memset (justs, 1, sizeof justs);
3284 byteval = i16val = u16val = i32val = u32val = i64val = u64val = hval = 88;
3288 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3289 &justs[0], &byteval,
3300 g_assert (!(justs[0] || justs[1] || justs[2] || justs[3] || justs[4] ||
3301 justs[5] || justs[6] || justs[7] || justs[8] || justs[9]));
3302 g_assert (byteval == '\0' && bval == FALSE);
3303 g_assert (i16val == 0 && u16val == 0 && i32val == 0 &&
3304 u32val == 0 && i64val == 0 && u64val == 0 &&
3305 hval == 0 && dval == 0.0);
3306 g_assert (vval == NULL);
3309 byteval = i16val = u16val = i32val = u32val = i64val = u64val = hval = 88;
3313 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3325 g_assert (byteval == '\0' && bval == FALSE);
3326 g_assert (i16val == 0 && u16val == 0 && i32val == 0 &&
3327 u32val == 0 && i64val == 0 && u64val == 0 &&
3328 hval == 0 && dval == 0.0);
3329 g_assert (vval == NULL);
3331 g_variant_unref (value);
3334 /* test all 'just' */
3335 value = g_variant_new ("(mymbmnmqmimumxmtmhmdmv)",
3339 TRUE, (guint16) 123,
3341 TRUE, (guint32) 123,
3343 TRUE, (guint64) 123,
3345 TRUE, (gdouble) 37.5,
3346 g_variant_new ("()"));
3349 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3363 memset (justs, 0, sizeof justs);
3364 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3376 g_assert (justs[0] && justs[1] && justs[2] && justs[3] && justs[4] &&
3377 justs[5] && justs[6] && justs[7] && justs[8] && justs[9]);
3380 memset (justs, 0, sizeof justs);
3381 byteval = i16val = u16val = i32val = u32val = i64val = u64val = hval = 88;
3385 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3386 &justs[0], &byteval,
3397 g_assert (justs[0] && justs[1] && justs[2] && justs[3] && justs[4] &&
3398 justs[5] && justs[6] && justs[7] && justs[8] && justs[9]);
3399 g_assert (byteval == 'a' && bval == TRUE);
3400 g_assert (i16val == 123 && u16val == 123 && i32val == 123 &&
3401 u32val == 123 && i64val == 123 && u64val == 123 &&
3402 hval == -1 && dval == 37.5);
3403 g_assert (g_variant_is_of_type (vval, G_VARIANT_TYPE_UNIT));
3404 g_variant_unref (vval);
3407 byteval = i16val = u16val = i32val = u32val = i64val = u64val = hval = 88;
3411 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3423 g_assert (byteval == 'a' && bval == TRUE);
3424 g_assert (i16val == 123 && u16val == 123 && i32val == 123 &&
3425 u32val == 123 && i64val == 123 && u64val == 123 &&
3426 hval == -1 && dval == 37.5);
3427 g_assert (g_variant_is_of_type (vval, G_VARIANT_TYPE_UNIT));
3428 g_variant_unref (vval);
3430 g_variant_unref (value);
3437 value = g_variant_new ("(masas)", NULL, NULL);
3438 g_variant_ref_sink (value);
3440 str = g_variant_print (value, TRUE);
3441 g_assert_cmpstr (str, ==, "(@mas nothing, @as [])");
3442 g_variant_unref (value);
3445 do_failed_test ("/gvariant/varargs/subprocess/empty-array",
3446 "*which type of empty array*");
3449 g_variant_type_info_assert_no_infos ();
3453 hash_get (GVariant *value,
3454 const gchar *format,
3457 const gchar *endptr = NULL;
3461 hash = g_str_has_suffix (format, "#");
3463 va_start (ap, format);
3464 g_variant_get_va (value, format, hash ? &endptr : NULL, &ap);
3468 g_assert (*endptr == '#');
3472 hash_new (const gchar *format,
3475 const gchar *endptr = NULL;
3480 hash = g_str_has_suffix (format, "#");
3482 va_start (ap, format);
3483 value = g_variant_new_va (format, hash ? &endptr : NULL, &ap);
3487 g_assert (*endptr == '#');
3499 value = hash_new ("i", 234);
3500 hash_get (value, "i", &x);
3501 g_assert (x == 234);
3502 g_variant_unref (value);
3505 value = hash_new ("i#", 234);
3506 hash_get (value, "i#", &x);
3507 g_assert (x == 234);
3508 g_variant_unref (value);
3510 g_variant_type_info_assert_no_infos ();
3514 test_builder_memory (void)
3516 GVariantBuilder *hb;
3519 hb = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
3520 g_variant_builder_open (hb, G_VARIANT_TYPE_ARRAY);
3521 g_variant_builder_open (hb, G_VARIANT_TYPE_ARRAY);
3522 g_variant_builder_open (hb, G_VARIANT_TYPE_ARRAY);
3523 g_variant_builder_add (hb, "s", "some value");
3524 g_variant_builder_ref (hb);
3525 g_variant_builder_unref (hb);
3526 g_variant_builder_unref (hb);
3528 hb = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
3529 g_variant_builder_unref (hb);
3531 hb = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
3532 g_variant_builder_clear (hb);
3533 g_variant_builder_unref (hb);
3535 g_variant_builder_init (&sb, G_VARIANT_TYPE_ARRAY);
3536 g_variant_builder_open (&sb, G_VARIANT_TYPE_ARRAY);
3537 g_variant_builder_open (&sb, G_VARIANT_TYPE_ARRAY);
3538 g_variant_builder_add (&sb, "s", "some value");
3539 g_variant_builder_clear (&sb);
3541 g_variant_type_info_assert_no_infos ();
3547 GVariant *items[4096];
3551 table = g_hash_table_new_full (g_variant_hash, g_variant_equal,
3552 (GDestroyNotify ) g_variant_unref,
3555 for (i = 0; i < G_N_ELEMENTS (items); i++)
3561 tree = tree_instance_new (NULL, 0);
3562 items[i] = tree_instance_get_gvariant (tree);
3563 tree_instance_free (tree);
3565 for (j = 0; j < i; j++)
3566 if (g_variant_equal (items[i], items[j]))
3568 g_variant_unref (items[i]);
3572 g_hash_table_insert (table,
3573 g_variant_ref_sink (items[i]),
3574 GINT_TO_POINTER (i));
3577 for (i = 0; i < G_N_ELEMENTS (items); i++)
3581 result = g_hash_table_lookup (table, items[i]);
3582 g_assert_cmpint (GPOINTER_TO_INT (result), ==, i);
3585 g_hash_table_unref (table);
3587 g_variant_type_info_assert_no_infos ();
3591 test_gv_byteswap (void)
3593 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
3594 # define native16(x) x, 0
3595 # define swapped16(x) 0, x
3597 # define native16(x) 0, x
3598 # define swapped16(x) x, 0
3600 /* all kinds of of crazy randomised testing already performed on the
3601 * byteswapper in the /gvariant/serialiser/byteswap test and all kinds
3602 * of crazy randomised testing performed against the serialiser
3603 * normalisation functions in the /gvariant/serialiser/fuzz/ tests.
3605 * just test a few simple cases here to make sure they each work
3607 guchar validbytes[] = { 'a', '\0', swapped16(66), 2,
3609 'b', '\0', swapped16(77), 2,
3611 guchar corruptbytes[] = { 'a', '\0', swapped16(66), 2,
3613 'b', '\0', swapped16(77), 2,
3615 guint valid_data[4], corrupt_data[4];
3616 GVariant *value, *swapped;
3617 gchar *string, *string2;
3619 memcpy (valid_data, validbytes, sizeof validbytes);
3620 memcpy (corrupt_data, corruptbytes, sizeof corruptbytes);
3623 value = g_variant_new_from_data (G_VARIANT_TYPE ("a(sn)"),
3624 valid_data, sizeof validbytes, TRUE,
3626 swapped = g_variant_byteswap (value);
3627 g_variant_unref (value);
3628 g_assert (g_variant_get_size (swapped) == 13);
3629 string = g_variant_print (swapped, FALSE);
3630 g_variant_unref (swapped);
3631 g_assert_cmpstr (string, ==, "[('a', 66), ('b', 77)]");
3634 /* untrusted but valid */
3635 value = g_variant_new_from_data (G_VARIANT_TYPE ("a(sn)"),
3636 valid_data, sizeof validbytes, FALSE,
3638 swapped = g_variant_byteswap (value);
3639 g_variant_unref (value);
3640 g_assert (g_variant_get_size (swapped) == 13);
3641 string = g_variant_print (swapped, FALSE);
3642 g_variant_unref (swapped);
3643 g_assert_cmpstr (string, ==, "[('a', 66), ('b', 77)]");
3646 /* untrusted, invalid */
3647 value = g_variant_new_from_data (G_VARIANT_TYPE ("a(sn)"),
3648 corrupt_data, sizeof corruptbytes, FALSE,
3650 string = g_variant_print (value, FALSE);
3651 swapped = g_variant_byteswap (value);
3652 g_variant_unref (value);
3653 g_assert (g_variant_get_size (swapped) == 13);
3654 value = g_variant_byteswap (swapped);
3655 g_variant_unref (swapped);
3656 string2 = g_variant_print (value, FALSE);
3657 g_assert (g_variant_get_size (value) == 13);
3658 g_variant_unref (value);
3659 g_assert_cmpstr (string, ==, string2);
3673 tree = tree_instance_new (NULL, 3);
3674 value = tree_instance_get_gvariant (tree);
3675 tree_instance_free (tree);
3677 pt = g_variant_print (value, TRUE);
3678 p = g_variant_print (value, FALSE);
3680 parsed = g_variant_parse (NULL, pt, NULL, NULL, NULL);
3681 res = g_variant_print (parsed, FALSE);
3682 g_assert_cmpstr (p, ==, res);
3683 g_variant_unref (parsed);
3686 parsed = g_variant_parse (g_variant_get_type (value), p,
3688 res = g_variant_print (parsed, TRUE);
3689 g_assert_cmpstr (pt, ==, res);
3690 g_variant_unref (parsed);
3693 g_variant_unref (value);
3703 for (i = 0; i < 100; i++)
3710 GError *error = NULL;
3715 for (i = 0; i < 127; i++)
3719 val = g_variant_new_string (str);
3720 p = g_variant_print (val, FALSE);
3721 g_variant_unref (val);
3723 val = g_variant_parse (NULL, p, NULL, NULL, &error);
3724 p2 = g_variant_print (val, FALSE);
3726 g_assert_cmpstr (str, ==, g_variant_get_string (val, NULL));
3727 g_assert_cmpstr (p, ==, p2);
3729 g_variant_unref (val);
3734 /* another mini test */
3739 value = g_variant_parse (G_VARIANT_TYPE_INT32, "1 2 3", NULL, &end, NULL);
3740 g_assert_cmpint (g_variant_get_int32 (value), ==, 1);
3741 /* make sure endptr returning works */
3742 g_assert_cmpstr (end, ==, " 2 3");
3743 g_variant_unref (value);
3746 /* unicode mini test */
3749 const gchar orig[] = "a\xc5\x82\xf0\x9d\x84\x9e \t\n";
3753 value = g_variant_new_string (orig);
3754 printed = g_variant_print (value, FALSE);
3755 g_variant_unref (value);
3757 g_assert_cmpstr (printed, ==, "'a\xc5\x82\xf0\x9d\x84\x9e \\t\\n'");
3758 value = g_variant_parse (NULL, printed, NULL, NULL, NULL);
3759 g_assert_cmpstr (g_variant_get_string (value, NULL), ==, orig);
3760 g_variant_unref (value);
3766 const gchar orig[] = " \342\200\254 \360\220\210\240 \a \b \f \n \r \t \v ";
3770 value = g_variant_new_string (orig);
3771 printed = g_variant_print (value, FALSE);
3772 g_variant_unref (value);
3774 g_assert_cmpstr (printed, ==, "' \\u202c \\U00010220 \\a \\b \\f \\n \\r \\t \\v '");
3775 value = g_variant_parse (NULL, printed, NULL, NULL, NULL);
3776 g_assert_cmpstr (g_variant_get_string (value, NULL), ==, orig);
3777 g_variant_unref (value);
3782 /* inf/nan strings are C99 features which Visual C++ does not support */
3783 /* inf/nan mini test */
3785 const gchar *tests[] = { "inf", "-inf", "nan" };
3788 gchar *printed_down;
3791 for (i = 0; i < G_N_ELEMENTS (tests); i++)
3793 GError *error = NULL;
3794 value = g_variant_parse (NULL, tests[i], NULL, NULL, &error);
3795 printed = g_variant_print (value, FALSE);
3796 /* Canonicalize to lowercase; https://bugzilla.gnome.org/show_bug.cgi?id=704585 */
3797 printed_down = g_ascii_strdown (printed, -1);
3798 g_assert (g_str_has_prefix (printed_down, tests[i]));
3800 g_free (printed_down);
3801 g_variant_unref (value);
3806 g_variant_type_info_assert_no_infos ();
3810 test_parse_failures (void)
3812 const gchar *test[] = {
3813 "[1, 2,", "6:", "expected value",
3814 "", "0:", "expected value",
3815 "(1, 2,", "6:", "expected value",
3816 "<1", "2:", "expected '>'",
3817 "[]", "0-2:", "unable to infer",
3818 "(,", "1:", "expected value",
3819 "[4,'']", "1-2,3-5:", "common type",
3820 "[4, '', 5]", "1-2,4-6:", "common type",
3821 "['', 4, 5]", "1-3,5-6:", "common type",
3822 "[4, 5, '']", "1-2,7-9:", "common type",
3823 "[[4], [], ['']]", "1-4,10-14:", "common type",
3824 "[[], [4], ['']]", "5-8,10-14:", "common type",
3825 "just", "4:", "expected value",
3826 "nothing", "0-7:", "unable to infer",
3827 "just [4, '']", "6-7,9-11:", "common type",
3828 "[[4,'']]", "2-3,4-6:", "common type",
3829 "([4,''],)", "2-3,4-6:", "common type",
3831 "{}", "0-2:", "unable to infer",
3832 "{[1,2],[3,4]}", "0-13:", "basic types",
3833 "{[1,2]:[3,4]}", "0-13:", "basic types",
3834 "justt", "0-5:", "unknown keyword",
3835 "nothng", "0-6:", "unknown keyword",
3836 "uint33", "0-6:", "unknown keyword",
3837 "@mi just ''", "9-11:", "can not parse as",
3838 "@ai ['']", "5-7:", "can not parse as",
3839 "@(i) ('',)", "6-8:", "can not parse as",
3840 "[[], 5]", "1-3,5-6:", "common type",
3841 "[[5], 5]", "1-4,6-7:", "common type",
3842 "5 5", "2:", "expected end of input",
3843 "[5, [5, '']]", "5-6,8-10:", "common type",
3844 "@i just 5", "3-9:", "can not parse as",
3845 "@i nothing", "3-10:", "can not parse as",
3846 "@i []", "3-5:", "can not parse as",
3847 "@i ()", "3-5:", "can not parse as",
3848 "@ai (4,)", "4-8:", "can not parse as",
3849 "@(i) []", "5-7:", "can not parse as",
3850 "(5 5)", "3:", "expected ','",
3851 "[5 5]", "3:", "expected ',' or ']'",
3852 "(5, 5 5)", "6:", "expected ',' or ')'",
3853 "[5, 5 5]", "6:", "expected ',' or ']'",
3854 "<@i []>", "4-6:", "can not parse as",
3855 "<[5 5]>", "4:", "expected ',' or ']'",
3856 "{[4,''],5}", "2-3,4-6:", "common type",
3857 "{5,[4,'']}", "4-5,6-8:", "common type",
3858 "@i {1,2}", "3-8:", "can not parse as",
3859 "{@i '', 5}", "4-6:", "can not parse as",
3860 "{5, @i ''}", "7-9:", "can not parse as",
3861 "@ai {}", "4-6:", "can not parse as",
3862 "{@i '': 5}", "4-6:", "can not parse as",
3863 "{5: @i ''}", "7-9:", "can not parse as",
3864 "{<4,5}", "3:", "expected '>'",
3865 "{4,<5}", "5:", "expected '>'",
3866 "{4,5,6}", "4:", "expected '}'",
3867 "{5 5}", "3:", "expected ':' or ','",
3868 "{4: 5: 6}", "5:", "expected ',' or '}'",
3869 "{4:5,<6:7}", "7:", "expected '>'",
3870 "{4:5,6:<7}", "9:", "expected '>'",
3871 "{4:5,6 7}", "7:", "expected ':'",
3872 "@o 'foo'", "3-8:", "object path",
3873 "@g 'zzz'", "3-8:", "signature",
3874 "@i true", "3-7:", "can not parse as",
3875 "@z 4", "0-2:", "invalid type",
3876 "@a* []", "0-3:", "definite",
3877 "@ai [3 3]", "7:", "expected ',' or ']'",
3878 "18446744073709551616", "0-20:", "too big for any type",
3879 "-18446744073709551616", "0-21:", "too big for any type",
3880 "byte 256", "5-8:", "out of range for type",
3881 "byte -1", "5-7:", "out of range for type",
3882 "int16 32768", "6-11:", "out of range for type",
3883 "int16 -32769", "6-12:", "out of range for type",
3884 "uint16 -1", "7-9:", "out of range for type",
3885 "uint16 65536", "7-12:", "out of range for type",
3886 "2147483648", "0-10:", "out of range for type",
3887 "-2147483649", "0-11:", "out of range for type",
3888 "uint32 -1", "7-9:", "out of range for type",
3889 "uint32 4294967296", "7-17:", "out of range for type",
3890 "@x 9223372036854775808", "3-22:", "out of range for type",
3891 "@x -9223372036854775809", "3-23:", "out of range for type",
3892 "@t -1", "3-5:", "out of range for type",
3893 "@t 18446744073709551616", "3-23:", "too big for any type",
3894 "handle 2147483648", "7-17:", "out of range for type",
3895 "handle -2147483649", "7-18:", "out of range for type",
3896 "1.798e308", "0-9:", "too big for any type",
3897 "37.5a488", "4-5:", "invalid character",
3898 "0x7ffgf", "5-6:", "invalid character",
3899 "07758", "4-5:", "invalid character",
3900 "123a5", "3-4:", "invalid character",
3901 "@ai 123", "4-7:", "can not parse as",
3902 "'\"\\'", "0-4:", "unterminated string",
3903 "'\"\\'\\", "0-5:", "unterminated string",
3904 "boolean 4", "8-9:", "can not parse as",
3905 "int32 true", "6-10:", "can not parse as",
3906 "[double 5, int32 5]", "1-9,11-18:", "common type",
3907 "string 4", "7-8:", "can not parse as"
3911 for (i = 0; i < G_N_ELEMENTS (test); i += 3)
3913 GError *error = NULL;
3916 value = g_variant_parse (NULL, test[i], NULL, NULL, &error);
3917 g_assert (value == NULL);
3919 if (!strstr (error->message, test[i+2]))
3920 g_error ("test %d: Can't find '%s' in '%s'", i / 3,
3921 test[i+2], error->message);
3923 if (!g_str_has_prefix (error->message, test[i+1]))
3924 g_error ("test %d: Expected location '%s' in '%s'", i / 3,
3925 test[i+1], error->message);
3927 g_error_free (error);
3932 test_parse_bad_format_char (void)
3934 g_variant_new_parsed ("%z");
3936 g_assert_not_reached ();
3940 test_parse_bad_format_string (void)
3942 g_variant_new_parsed ("uint32 %i", 2);
3944 g_assert_not_reached ();
3948 test_parse_bad_args (void)
3950 g_variant_new_parsed ("%@i", g_variant_new_uint32 (2));
3952 g_assert_not_reached ();
3956 test_parse_positional (void)
3959 check_and_free (g_variant_new_parsed ("[('one', 1), (%s, 2),"
3960 " ('three', %i)]", "two", 3),
3961 "[('one', 1), ('two', 2), ('three', 3)]");
3962 value = g_variant_new_parsed ("[('one', 1), (%s, 2),"
3963 " ('three', %u)]", "two", 3);
3964 g_assert (g_variant_is_of_type (value, G_VARIANT_TYPE ("a(su)")));
3965 check_and_free (value, "[('one', 1), ('two', 2), ('three', 3)]");
3966 check_and_free (g_variant_new_parsed ("{%s:%i}", "one", 1), "{'one': 1}");
3968 if (g_test_undefined ())
3970 do_failed_test ("/gvariant/parse/subprocess/bad-format-char",
3971 "*GVariant format string*");
3973 do_failed_test ("/gvariant/parse/subprocess/bad-format-string",
3974 "*can not parse as*");
3976 do_failed_test ("/gvariant/parse/subprocess/bad-args",
3977 "*expected GVariant of type 'i'*");
3982 test_floating (void)
3986 value = g_variant_new_int32 (42);
3987 g_assert (g_variant_is_floating (value));
3988 g_variant_ref_sink (value);
3989 g_assert (!g_variant_is_floating (value));
3990 g_variant_unref (value);
3994 test_bytestring (void)
3996 const gchar *test_string = "foo,bar,baz,quux,\xffoooo";
4000 const gchar *const_str;
4001 GVariant *untrusted_empty;
4003 strv = g_strsplit (test_string, ",", 0);
4005 value = g_variant_new_bytestring_array ((const gchar **) strv, -1);
4006 g_assert (g_variant_is_floating (value));
4009 str = g_variant_print (value, FALSE);
4010 g_variant_unref (value);
4012 value = g_variant_parse (NULL, str, NULL, NULL, NULL);
4015 strv = g_variant_dup_bytestring_array (value, NULL);
4016 g_variant_unref (value);
4018 str = g_strjoinv (",", strv);
4021 g_assert_cmpstr (str, ==, test_string);
4024 strv = g_strsplit (test_string, ",", 0);
4025 value = g_variant_new ("(^aay^a&ay^ay^&ay)",
4026 strv, strv, strv[0], strv[0]);
4029 g_variant_get_child (value, 0, "^a&ay", &strv);
4030 str = g_strjoinv (",", strv);
4032 g_assert_cmpstr (str, ==, test_string);
4035 g_variant_get_child (value, 0, "^aay", &strv);
4036 str = g_strjoinv (",", strv);
4038 g_assert_cmpstr (str, ==, test_string);
4041 g_variant_get_child (value, 1, "^a&ay", &strv);
4042 str = g_strjoinv (",", strv);
4044 g_assert_cmpstr (str, ==, test_string);
4047 g_variant_get_child (value, 1, "^aay", &strv);
4048 str = g_strjoinv (",", strv);
4050 g_assert_cmpstr (str, ==, test_string);
4053 g_variant_get_child (value, 2, "^ay", &str);
4054 g_assert_cmpstr (str, ==, "foo");
4057 g_variant_get_child (value, 2, "^&ay", &str);
4058 g_assert_cmpstr (str, ==, "foo");
4060 g_variant_get_child (value, 3, "^ay", &str);
4061 g_assert_cmpstr (str, ==, "foo");
4064 g_variant_get_child (value, 3, "^&ay", &str);
4065 g_assert_cmpstr (str, ==, "foo");
4066 g_variant_unref (value);
4068 untrusted_empty = g_variant_new_from_data (G_VARIANT_TYPE ("ay"), NULL, 0, FALSE, NULL, NULL);
4069 value = g_variant_get_normal_form (untrusted_empty);
4070 const_str = g_variant_get_bytestring (value);
4072 g_variant_unref (value);
4073 g_variant_unref (untrusted_empty);
4077 test_lookup_value (void)
4080 const gchar *dict, *key, *value;
4082 { "@a{ss} {'x': 'y'}", "x", "'y'" },
4083 { "@a{ss} {'x': 'y'}", "y" },
4084 { "@a{os} {'/x': 'y'}", "/x", "'y'" },
4085 { "@a{os} {'/x': 'y'}", "/y" },
4086 { "@a{sv} {'x': <'y'>}", "x", "'y'" },
4087 { "@a{sv} {'x': <5>}", "x", "5" },
4088 { "@a{sv} {'x': <'y'>}", "y" }
4092 for (i = 0; i < G_N_ELEMENTS (cases); i++)
4094 GVariant *dictionary;
4098 dictionary = g_variant_parse (NULL, cases[i].dict, NULL, NULL, NULL);
4099 value = g_variant_lookup_value (dictionary, cases[i].key, NULL);
4100 g_variant_unref (dictionary);
4102 if (value == NULL && cases[i].value == NULL)
4105 g_assert (value && cases[i].value);
4106 p = g_variant_print (value, FALSE);
4107 g_assert_cmpstr (cases[i].value, ==, p);
4108 g_variant_unref (value);
4121 dict = g_variant_parse (NULL,
4122 "{'a': <5>, 'b': <'c'>}",
4125 ok = g_variant_lookup (dict, "a", "i", &num);
4127 g_assert_cmpint (num, ==, 5);
4129 ok = g_variant_lookup (dict, "a", "&s", &str);
4132 ok = g_variant_lookup (dict, "q", "&s", &str);
4135 ok = g_variant_lookup (dict, "b", "i", &num);
4138 ok = g_variant_lookup (dict, "b", "&s", &str);
4140 g_assert_cmpstr (str, ==, "c");
4142 ok = g_variant_lookup (dict, "q", "&s", &str);
4145 g_variant_unref (dict);
4149 untrusted (GVariant *a)
4152 const GVariantType *type;
4155 type = g_variant_get_type (a);
4156 bytes = g_variant_get_data_as_bytes (a);
4157 b = g_variant_new_from_bytes (type, bytes, FALSE);
4158 g_bytes_unref (bytes);
4159 g_variant_unref (a);
4170 a = untrusted (g_variant_new_byte (5));
4171 b = g_variant_new_byte (6);
4172 g_assert (g_variant_compare (a, b) < 0);
4173 g_variant_unref (a);
4174 g_variant_unref (b);
4175 a = untrusted (g_variant_new_int16 (G_MININT16));
4176 b = g_variant_new_int16 (G_MAXINT16);
4177 g_assert (g_variant_compare (a, b) < 0);
4178 g_variant_unref (a);
4179 g_variant_unref (b);
4180 a = untrusted (g_variant_new_uint16 (0));
4181 b = g_variant_new_uint16 (G_MAXUINT16);
4182 g_assert (g_variant_compare (a, b) < 0);
4183 g_variant_unref (a);
4184 g_variant_unref (b);
4185 a = untrusted (g_variant_new_int32 (G_MININT32));
4186 b = g_variant_new_int32 (G_MAXINT32);
4187 g_assert (g_variant_compare (a, b) < 0);
4188 g_variant_unref (a);
4189 g_variant_unref (b);
4190 a = untrusted (g_variant_new_uint32 (0));
4191 b = g_variant_new_uint32 (G_MAXUINT32);
4192 g_assert (g_variant_compare (a, b) < 0);
4193 g_variant_unref (a);
4194 g_variant_unref (b);
4195 a = untrusted (g_variant_new_int64 (G_MININT64));
4196 b = g_variant_new_int64 (G_MAXINT64);
4197 g_assert (g_variant_compare (a, b) < 0);
4198 g_variant_unref (a);
4199 g_variant_unref (b);
4200 a = untrusted (g_variant_new_uint64 (0));
4201 b = g_variant_new_uint64 (G_MAXUINT64);
4202 g_assert (g_variant_compare (a, b) < 0);
4203 g_variant_unref (a);
4204 g_variant_unref (b);
4205 a = untrusted (g_variant_new_double (G_MINDOUBLE));
4206 b = g_variant_new_double (G_MAXDOUBLE);
4207 g_assert (g_variant_compare (a, b) < 0);
4208 g_variant_unref (a);
4209 g_variant_unref (b);
4210 a = untrusted (g_variant_new_string ("abc"));
4211 b = g_variant_new_string ("abd");
4212 g_assert (g_variant_compare (a, b) < 0);
4213 g_variant_unref (a);
4214 g_variant_unref (b);
4215 a = untrusted (g_variant_new_object_path ("/abc"));
4216 b = g_variant_new_object_path ("/abd");
4217 g_assert (g_variant_compare (a, b) < 0);
4218 g_variant_unref (a);
4219 g_variant_unref (b);
4220 a = untrusted (g_variant_new_signature ("g"));
4221 b = g_variant_new_signature ("o");
4222 g_assert (g_variant_compare (a, b) < 0);
4223 g_variant_unref (a);
4224 g_variant_unref (b);
4225 a = untrusted (g_variant_new_boolean (FALSE));
4226 b = g_variant_new_boolean (TRUE);
4227 g_assert (g_variant_compare (a, b) < 0);
4228 g_variant_unref (a);
4229 g_variant_unref (b);
4238 a = untrusted (g_variant_new_byte (5));
4239 b = g_variant_get_normal_form (a);
4240 g_assert (g_variant_equal (a, b));
4241 g_variant_unref (a);
4242 g_variant_unref (b);
4243 a = untrusted (g_variant_new_int16 (G_MININT16));
4244 b = g_variant_get_normal_form (a);
4245 g_assert (g_variant_equal (a, b));
4246 g_variant_unref (a);
4247 g_variant_unref (b);
4248 a = untrusted (g_variant_new_uint16 (0));
4249 b = g_variant_get_normal_form (a);
4250 g_assert (g_variant_equal (a, b));
4251 g_variant_unref (a);
4252 g_variant_unref (b);
4253 a = untrusted (g_variant_new_int32 (G_MININT32));
4254 b = g_variant_get_normal_form (a);
4255 g_assert (g_variant_equal (a, b));
4256 g_variant_unref (a);
4257 g_variant_unref (b);
4258 a = untrusted (g_variant_new_uint32 (0));
4259 b = g_variant_get_normal_form (a);
4260 g_assert (g_variant_equal (a, b));
4261 g_variant_unref (a);
4262 g_variant_unref (b);
4263 a = untrusted (g_variant_new_int64 (G_MININT64));
4264 b = g_variant_get_normal_form (a);
4265 g_assert (g_variant_equal (a, b));
4266 g_variant_unref (a);
4267 g_variant_unref (b);
4268 a = untrusted (g_variant_new_uint64 (0));
4269 b = g_variant_get_normal_form (a);
4270 g_assert (g_variant_equal (a, b));
4271 g_variant_unref (a);
4272 g_variant_unref (b);
4273 a = untrusted (g_variant_new_double (G_MINDOUBLE));
4274 b = g_variant_get_normal_form (a);
4275 g_assert (g_variant_equal (a, b));
4276 g_variant_unref (a);
4277 g_variant_unref (b);
4278 a = untrusted (g_variant_new_string ("abc"));
4279 g_assert (g_variant_equal (a, a));
4280 b = g_variant_get_normal_form (a);
4281 g_assert (g_variant_equal (a, b));
4282 g_variant_unref (a);
4283 g_variant_unref (b);
4284 a = untrusted (g_variant_new_object_path ("/abc"));
4285 g_assert (g_variant_equal (a, a));
4286 b = g_variant_get_normal_form (a);
4288 g_assert (g_variant_equal (a, b));
4289 g_variant_unref (a);
4290 g_variant_unref (b);
4291 a = untrusted (g_variant_new_signature ("g"));
4292 g_assert (g_variant_equal (a, a));
4293 b = g_variant_get_normal_form (a);
4295 g_assert (g_variant_equal (a, b));
4296 g_variant_unref (a);
4297 g_variant_unref (b);
4298 a = untrusted (g_variant_new_boolean (FALSE));
4299 b = g_variant_get_normal_form (a);
4300 g_assert (g_variant_equal (a, b));
4301 g_variant_unref (a);
4302 g_variant_unref (b);
4306 test_fixed_array (void)
4315 a = g_variant_new_parsed ("[1,2,3,4,5]");
4316 elts = g_variant_get_fixed_array (a, &n_elts, sizeof (gint32));
4317 g_assert (n_elts == 5);
4318 for (i = 0; i < 5; i++)
4319 g_assert_cmpint (elts[i], ==, i + 1);
4320 g_variant_unref (a);
4323 for (i = 0; i < 5; i++)
4325 a = g_variant_new_fixed_array (G_VARIANT_TYPE_INT32, values,
4326 G_N_ELEMENTS (values), sizeof (values[0]));
4327 g_assert_cmpstr (g_variant_get_type_string (a), ==, "ai");
4328 elts = g_variant_get_fixed_array (a, &n_elts, sizeof (gint32));
4329 g_assert (n_elts == 5);
4330 for (i = 0; i < 5; i++)
4331 g_assert_cmpint (elts[i], ==, i + 1);
4332 g_variant_unref (a);
4336 test_check_format_string (void)
4340 value = g_variant_new ("(sas)", "foo", NULL);
4341 g_variant_ref_sink (value);
4343 g_assert (g_variant_check_format_string (value, "(s*)", TRUE));
4344 g_assert (g_variant_check_format_string (value, "(s*)", FALSE));
4345 g_assert (!g_variant_check_format_string (value, "(u*)", TRUE));
4346 g_assert (!g_variant_check_format_string (value, "(u*)", FALSE));
4348 g_assert (g_variant_check_format_string (value, "(&s*)", FALSE));
4349 g_test_expect_message ("GLib", G_LOG_LEVEL_CRITICAL, "*contains a '&' character*");
4350 g_assert (!g_variant_check_format_string (value, "(&s*)", TRUE));
4351 g_test_assert_expected_messages ();
4353 g_assert (g_variant_check_format_string (value, "(s^as)", TRUE));
4354 g_assert (g_variant_check_format_string (value, "(s^as)", FALSE));
4356 g_test_expect_message ("GLib", G_LOG_LEVEL_CRITICAL, "*contains a '&' character*");
4357 g_assert (!g_variant_check_format_string (value, "(s^a&s)", TRUE));
4358 g_test_assert_expected_messages ();
4359 g_assert (g_variant_check_format_string (value, "(s^a&s)", FALSE));
4361 g_variant_unref (value);
4363 /* Do it again with a type that will let us put a '&' after a '^' */
4364 value = g_variant_new ("(say)", "foo", NULL);
4365 g_variant_ref_sink (value);
4367 g_assert (g_variant_check_format_string (value, "(s*)", TRUE));
4368 g_assert (g_variant_check_format_string (value, "(s*)", FALSE));
4369 g_assert (!g_variant_check_format_string (value, "(u*)", TRUE));
4370 g_assert (!g_variant_check_format_string (value, "(u*)", FALSE));
4372 g_assert (g_variant_check_format_string (value, "(&s*)", FALSE));
4373 g_test_expect_message ("GLib", G_LOG_LEVEL_CRITICAL, "*contains a '&' character*");
4374 g_assert (!g_variant_check_format_string (value, "(&s*)", TRUE));
4375 g_test_assert_expected_messages ();
4377 g_assert (g_variant_check_format_string (value, "(s^ay)", TRUE));
4378 g_assert (g_variant_check_format_string (value, "(s^ay)", FALSE));
4380 g_test_expect_message ("GLib", G_LOG_LEVEL_CRITICAL, "*contains a '&' character*");
4381 g_assert (!g_variant_check_format_string (value, "(s^&ay)", TRUE));
4382 g_test_assert_expected_messages ();
4383 g_assert (g_variant_check_format_string (value, "(s^&ay)", FALSE));
4385 g_assert (g_variant_check_format_string (value, "r", FALSE));
4386 g_assert (g_variant_check_format_string (value, "(?a?)", FALSE));
4388 g_variant_unref (value);
4392 verify_gvariant_checksum (const gchar *sha256,
4397 checksum = g_compute_checksum_for_data (G_CHECKSUM_SHA256,
4398 g_variant_get_data (v),
4399 g_variant_get_size (v));
4400 g_assert_cmpstr (sha256, ==, checksum);
4405 verify_gvariant_checksum_va (const gchar *sha256,
4412 va_start (args, fmt);
4414 v = g_variant_new_va (fmt, NULL, &args);
4415 g_variant_ref_sink (v);
4416 #if G_BYTE_ORDER == G_BIG_ENDIAN
4418 GVariant *byteswapped = g_variant_byteswap (v);
4419 g_variant_unref (v);
4426 verify_gvariant_checksum (sha256, v);
4428 g_variant_unref (v);
4432 test_checksum_basic (void)
4434 verify_gvariant_checksum_va ("e8a4b2ee7ede79a3afb332b5b6cc3d952a65fd8cffb897f5d18016577c33d7cc",
4436 verify_gvariant_checksum_va ("c53e363c33b00cfce298229ee83856b8a98c2e6126cab13f65899f62473b0df5",
4438 verify_gvariant_checksum_va ("2b4c342f5433ebe591a1da77e013d1b72475562d48578dca8b84bac6651c3cb9",
4440 verify_gvariant_checksum_va ("12a3ae445661ce5dee78d0650d33362dec29c4f82af05e7e57fb595bbbacf0ca",
4442 verify_gvariant_checksum_va ("e25a59b24440eb6c833aa79c93b9840e6eab6966add0dacf31df7e9e7000f5b3",
4444 verify_gvariant_checksum_va ("4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a",
4446 verify_gvariant_checksum_va ("ca2fd00fa001190744c15c317643ab092e7048ce086a243e2be9437c898de1bb",
4451 test_checksum_nested (void)
4453 static const char* const strv[] = {"foo", "bar", "baz", NULL};
4455 verify_gvariant_checksum_va ("31fbc92f08fddaca716188fe4b5d44ae122fc6306fd3c6925af53cfa47ea596d",
4457 verify_gvariant_checksum_va ("01759d683cead856d1d386d59af0578841698a424a265345ad5413122f220de8",
4458 "(su)", "moocow", 79);
4459 verify_gvariant_checksum_va ("52b3ae95f19b3e642ea1d01185aea14a09004c1d1712672644427403a8a0afe6",
4460 "(qyst)", G_MAXUINT16, 9, "moocow", G_MAXUINT64);
4461 verify_gvariant_checksum_va ("6fc6f4524161c3ae0d316812d7088e3fcd372023edaea2d7821093be40ae1060",
4462 "(@ay)", g_variant_new_bytestring ("\xFF\xFF\xFF"));
4463 verify_gvariant_checksum_va ("572aca386e1a983dd23bb6eb6e3dfa72eef9ca7c7744581aa800e18d7d9d0b0b",
4465 verify_gvariant_checksum_va ("4bddf6174c791bb44fc6a4106573031690064df34b741033a0122ed8dc05bcf3",
4466 "(yvu)", 254, g_variant_new ("(^as)", strv), 42);
4476 const guint8 values[5] = { 1, 2, 3, 4, 5 };
4481 bytes = g_bytes_new (&values, 5);
4482 a = g_variant_new_from_bytes (G_VARIANT_TYPE_BYTESTRING, bytes, TRUE);
4483 g_bytes_unref (bytes);
4485 elts = g_variant_get_fixed_array (a, &n_elts, sizeof (guint8));
4486 g_assert (n_elts == 5);
4487 for (i = 0; i < 5; i++)
4488 g_assert_cmpint (elts[i], ==, i + 1);
4490 bytes2 = g_variant_get_data_as_bytes (a);
4491 g_variant_unref (a);
4493 bytes = g_bytes_new (&values, 5);
4494 g_assert (g_bytes_equal (bytes, bytes2));
4495 g_bytes_unref (bytes);
4496 g_bytes_unref (bytes2);
4498 tuple = g_variant_new_parsed ("['foo', 'bar']");
4499 bytes = g_variant_get_data_as_bytes (tuple); /* force serialisation */
4500 a = g_variant_get_child_value (tuple, 1);
4501 bytes2 = g_variant_get_data_as_bytes (a);
4502 g_assert (!g_bytes_equal (bytes, bytes2));
4504 g_bytes_unref (bytes);
4505 g_bytes_unref (bytes2);
4506 g_variant_unref (a);
4507 g_variant_unref (tuple);
4511 const GVariantType *type;
4517 test_print_context (void)
4519 ContextTest tests[] = {
4520 { NULL, "(1, 2, 3, 'abc", " ^^^^" },
4521 { NULL, "[1, 2, 3, 'str']", " ^ ^^^^^" },
4522 { G_VARIANT_TYPE_UINT16, "{ 'abc':'def' }", " ^^^^^^^^^^^^^^^" },
4523 { NULL, "<5", " ^" },
4524 { NULL, "'ab\\ux'", " ^^^^^^^" },
4525 { NULL, "'ab\\U00efx'", " ^^^^^^^^^^^" }
4530 GError *error = NULL;
4532 for (i = 0; i < G_N_ELEMENTS (tests); i++)
4534 v = g_variant_parse (tests[i].type, tests[i].in, NULL, NULL, &error);
4536 s = g_variant_parse_error_print_context (error, tests[i].in);
4537 g_assert (strstr (s, tests[i].out) != NULL);
4539 g_clear_error (&error);
4544 test_error_quark (void)
4546 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
4547 g_assert (g_variant_parser_get_error_quark () == g_variant_parse_error_quark ());
4548 G_GNUC_END_IGNORE_DEPRECATIONS
4552 flatten_vectors (GVariantVectors *v)
4557 result = g_byte_array_new ();
4559 for (i = 0; i < v->vectors->len; i++)
4561 GVariantVector vec = g_array_index (v->vectors, GVariantVector, i);
4564 g_byte_array_append (result, vec.data.pointer, vec.size);
4566 g_byte_array_append (result, v->extra_bytes->data + vec.data.offset, vec.size);
4573 test_vector_serialiser (void)
4575 GVariantVectors vectors;
4576 GByteArray *flattened;
4580 for (i = 0; i < 100; i++)
4582 value = create_random_gvariant (4);
4584 GLIB_PRIVATE_CALL(g_variant_to_vectors) (value, &vectors);
4585 flattened = flatten_vectors (&vectors);
4586 g_byte_array_free (vectors.extra_bytes, TRUE);
4587 g_byte_array_free (vectors.offsets, TRUE);
4588 g_array_free (vectors.vectors, TRUE);
4591 if (flattened->len != g_variant_get_size (value) ||
4592 memcmp (flattened->data, g_variant_get_data (value), flattened->len) != 0)
4594 g_file_set_contents ("flattened", flattened->data, flattened->len, NULL);
4595 g_file_set_contents ("serialised", g_variant_get_data (value), g_variant_get_size (value), NULL);
4596 g_print ("type is %s\n", g_variant_get_type_string (value));
4597 g_assert_not_reached ();
4601 g_assert_cmpint (flattened->len, ==, g_variant_get_size (value));
4602 g_assert (memcmp (flattened->data, g_variant_get_data (value), flattened->len) == 0);
4604 g_byte_array_free (flattened, TRUE);
4605 g_variant_unref (value);
4610 main (int argc, char **argv)
4614 g_test_init (&argc, &argv, NULL);
4616 g_test_add_func ("/gvariant/type", test_gvarianttype);
4617 g_test_add_func ("/gvariant/typeinfo", test_gvarianttypeinfo);
4618 g_test_add_func ("/gvariant/serialiser/maybe", test_maybes);
4619 g_test_add_func ("/gvariant/serialiser/array", test_arrays);
4620 g_test_add_func ("/gvariant/serialiser/tuple", test_tuples);
4621 g_test_add_func ("/gvariant/serialiser/variant", test_variants);
4622 g_test_add_func ("/gvariant/serialiser/strings", test_strings);
4623 g_test_add_func ("/gvariant/serialiser/byteswap", test_byteswaps);
4625 for (i = 1; i <= 20; i += 4)
4629 testname = g_strdup_printf ("/gvariant/serialiser/fuzz/%d%%", i);
4630 g_test_add_data_func (testname, GINT_TO_POINTER (i),
4631 (gpointer) test_fuzzes);
4635 g_test_add_func ("/gvariant/string", test_string);
4636 g_test_add_func ("/gvariant/utf8", test_utf8);
4637 g_test_add_func ("/gvariant/containers", test_containers);
4638 g_test_add_func ("/gvariant/format-strings", test_format_strings);
4639 g_test_add_func ("/gvariant/invalid-varargs", test_invalid_varargs);
4640 g_test_add_func ("/gvariant/varargs", test_varargs);
4641 g_test_add_func ("/gvariant/varargs/subprocess/empty-array", test_varargs_empty_array);
4642 g_test_add_func ("/gvariant/valist", test_valist);
4643 g_test_add_func ("/gvariant/builder-memory", test_builder_memory);
4644 g_test_add_func ("/gvariant/hashing", test_hashing);
4645 g_test_add_func ("/gvariant/byteswap", test_gv_byteswap);
4646 g_test_add_func ("/gvariant/parser", test_parses);
4647 g_test_add_func ("/gvariant/parse-failures", test_parse_failures);
4648 g_test_add_func ("/gvariant/parse-positional", test_parse_positional);
4649 g_test_add_func ("/gvariant/parse/subprocess/bad-format-char", test_parse_bad_format_char);
4650 g_test_add_func ("/gvariant/parse/subprocess/bad-format-string", test_parse_bad_format_string);
4651 g_test_add_func ("/gvariant/parse/subprocess/bad-args", test_parse_bad_args);
4652 g_test_add_func ("/gvariant/floating", test_floating);
4653 g_test_add_func ("/gvariant/bytestring", test_bytestring);
4654 g_test_add_func ("/gvariant/lookup-value", test_lookup_value);
4655 g_test_add_func ("/gvariant/lookup", test_lookup);
4656 g_test_add_func ("/gvariant/compare", test_compare);
4657 g_test_add_func ("/gvariant/equal", test_equal);
4658 g_test_add_func ("/gvariant/fixed-array", test_fixed_array);
4659 g_test_add_func ("/gvariant/check-format-string", test_check_format_string);
4661 g_test_add_func ("/gvariant/checksum-basic", test_checksum_basic);
4662 g_test_add_func ("/gvariant/checksum-nested", test_checksum_nested);
4664 g_test_add_func ("/gvariant/gbytes", test_gbytes);
4665 g_test_add_func ("/gvariant/print-context", test_print_context);
4666 g_test_add_func ("/gvariant/error-quark", test_error_quark);
4667 g_test_add_func ("/gvariant/vector-serialiser", test_vector_serialiser);
4669 return g_test_run ();