diff --git a/glib/gvariant.c b/glib/gvariant.c index 2c9f951b3..d45b487ad 100644 --- a/glib/gvariant.c +++ b/glib/gvariant.c @@ -4662,7 +4662,15 @@ g_variant_valist_free_nnp (const gchar *str, break; case '^': - if (str[2] != '&') /* '^as', '^ao' */ + if (g_str_has_suffix (str, "y")) + { + if (str[2] != 'a') /* '^a&ay', '^ay' */ + g_free (ptr); + else if (str[1] == 'a') /* '^aay' */ + g_strfreev (ptr); + break; /* '^&ay' */ + } + else if (str[2] != '&') /* '^as', '^ao' */ g_strfreev (ptr); else /* '^a&s', '^a&o' */ g_free (ptr); diff --git a/glib/tests/gvariant.c b/glib/tests/gvariant.c index 54cef6777..8047ef5e8 100644 --- a/glib/tests/gvariant.c +++ b/glib/tests/gvariant.c @@ -3115,6 +3115,80 @@ test_varargs (void) g_free (strv); } + { + const gchar *strvector[] = {"/hello", "/world", NULL}; + const gchar *test_strs[] = {"/foo", "/bar", "/baz" }; + GVariantBuilder builder; + GVariantIter *array; + GVariantIter tuple; + const gchar **strv; + gchar **my_strv; + GVariant *value; + gchar *str; + gint i; + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("aaay")); + g_variant_builder_add (&builder, "^aay", strvector); + g_variant_builder_add (&builder, "^aay", strvector); + g_variant_builder_add (&builder, "^aay", strvector); + value = g_variant_new ("aaay", &builder); + array = g_variant_iter_new (value); + i = 0; + while (g_variant_iter_loop (array, "^aay", &my_strv)) + i++; + g_assert (i == 3); + + /* start over */ + g_variant_iter_init (array, value); + i = 0; + while (g_variant_iter_loop (array, "^a&ay", &strv)) + i++; + g_assert (i == 3); + g_variant_unref (value); + g_variant_iter_free (array); + + /* next test */ + g_variant_builder_init (&builder, G_VARIANT_TYPE ("aay")); + g_variant_builder_add (&builder, "^ay", "/foo"); + g_variant_builder_add (&builder, "^ay", "/bar"); + g_variant_builder_add (&builder, "^ay", "/baz"); + value = g_variant_new ("(aay^aay^a&ay)", &builder, strvector, strvector); + g_variant_iter_init (&tuple, value); + g_variant_iter_next (&tuple, "aay", &array); + + i = 0; + while (g_variant_iter_loop (array, "^ay", &str)) + g_assert_cmpstr (str, ==, test_strs[i++]); + g_assert (i == 3); + + g_variant_iter_free (array); + + /* start over */ + g_variant_iter_init (&tuple, value); + g_variant_iter_next (&tuple, "aay", &array); + + i = 0; + while (g_variant_iter_loop (array, "^&ay", &str)) + g_assert_cmpstr (str, ==, test_strs[i++]); + g_assert (i == 3); + + g_variant_iter_free (array); + + g_variant_iter_next (&tuple, "^a&ay", &strv); + g_variant_iter_next (&tuple, "^aay", &my_strv); + + g_assert_cmpstr (strv[0], ==, "/hello"); + g_assert_cmpstr (strv[1], ==, "/world"); + g_assert (strv[2] == NULL); + g_assert_cmpstr (my_strv[0], ==, "/hello"); + g_assert_cmpstr (my_strv[1], ==, "/world"); + g_assert (my_strv[2] == NULL); + + g_variant_unref (value); + g_strfreev (my_strv); + g_free (strv); + } + { const gchar *strvector[] = {"/hello", "/world", NULL}; const gchar *test_strs[] = {"/foo", "/bar", "/baz" };