mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-03-28 02:20:04 +01:00
gvariant-core: Add a note about memory safety of children
When g_variant_get_child() is called on a variant which has not been serialized, it serializes it which includes a call to g_variant_release_children() and therefore means that any children previously retrieved from the variant are no longer valid (unless another reference is held on them) and consequently values borrowed from those children are no longer safe to access. Add a note to the g_variant_get_child_value() documentation to explain this. Alternatively, we could say that after the child is freed, values borrowed from it are no longer valid. But we already have an implementation which hasn't changed in years which lets them stay valid if the variant was serialized before the first g_variant_get_child_value() call. Here's a demonstration of the memory error: static const char *get_first_child (GVariant *v) { g_autoptr(GVariant) child_v = g_variant_get_child_value (v, 0); return g_variant_get_string (child_v, NULL); } int main(int argc, char **argv) { g_autoptr(GVariant) v = g_variant_new("(@ss)", g_variant_new_string ("hello"), "world"); const char *child1 = get_first_child (v); const char *child2; g_variant_get_child (v, 1, "&s", &child2); printf ("%s\n", child1); // this is a memory error return 0; }
This commit is contained in:
parent
de8708cd95
commit
51b822787e
@ -1026,6 +1026,12 @@ g_variant_n_children (GVariant *value)
|
||||
* The returned value is never floating. You should free it with
|
||||
* g_variant_unref() when you're done with it.
|
||||
*
|
||||
* Note that values borrowed from the returned child are not guaranteed to
|
||||
* still be valid after the child is freed even if you still hold a reference
|
||||
* to @value, if @value has not been serialised at the time this function is
|
||||
* called. To avoid this, you can serialize @value by calling
|
||||
* g_variant_get_data() and optionally ignoring the return value.
|
||||
*
|
||||
* There may be implementation specific restrictions on deeply nested values,
|
||||
* which would result in the unit tuple being returned as the child value,
|
||||
* instead of further nested children. #GVariant is guaranteed to handle
|
||||
|
Loading…
x
Reference in New Issue
Block a user