g_variant_type_first() and g_variant_type_next() not usable from bindings
@creiter
Submitted by Christoph Reiter Assigned to Allison (desrt)
Link to original bug (#792821)
Description
Problem
GVariantType is a boxed and both g_variant_type_first() and g_variant_type_next() return with transfer-none. Which in turn requires the bindings to use g_boxed_copy(), which for GVariantType means calling g_variant_type_copy().
g_variant_type_copy() uses g_variant_type_get_string_length() for copying the object, but g_variant_type_get_string_length() returns a bogus value for the iterator returned by g_variant_type_first()/next(), so the returned instance is bogus as well.
Possible hacky solution
Add new variants of first()/next() which assume that the variant is null terminated and return transfer-full using strcpy instead of g_variant_type_get_string_length(). Alias these over the other ones for bindings.
Problem is that these new functions would crash if used on a not null terminated string. But this shouldn't be the case with bindings as they always have to either copy or get a copy, which is always null terminated.
Example program
#include <glib.h>
#include <glib.h>
#include <glib-object.h>
int
main (int argc,
char *argv[])
{
const GVariantType *gv = G_VARIANT_TYPE ("(si)");
const GVariantType *temp;
temp = g_variant_type_first (gv);
GVariantType *copy = g_boxed_copy (G_TYPE_VARIANT_TYPE, temp);
g_print ("%d, %d\n", g_variant_type_get_string_length (temp), g_variant_type_get_string_length (copy));
g_print ("%s\n", g_variant_type_dup_string (temp));
temp = g_variant_type_next(temp);
g_print ("%s\n", g_variant_type_dup_string (temp));
// the copy should behave the same, but doesn't
g_print ("%s\n", g_variant_type_dup_string (copy));
temp = g_variant_type_next(copy);
g_print ("%s\n", g_variant_type_dup_string (temp));
return 0;
}