From 1cbc21ad1101813ea7028a3679e77c141c36c306 Mon Sep 17 00:00:00 2001 From: Dorota Czaplejewicz Date: Mon, 3 Feb 2020 14:46:49 +0000 Subject: [PATCH] variant: Fix double-free gio::Settings::set_value takes over ownership of the Variant sometimes, but in other cases it doesn't. To prevent this being a problem, the custom Variant is made of the type that will never have its ownership taken. This is not necessarily consistent with what gtk-rs authors intended. In practice, the ownership is shared by refcounting, and after the Rust reference is dropped, one taken by Settings survives. --- src/popover.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/popover.rs b/src/popover.rs index 5f0f735f..ce1543ba 100644 --- a/src/popover.rs +++ b/src/popover.rs @@ -91,6 +91,11 @@ mod variants { unsafe { let ret = glib_sys::g_variant_builder_end(builder); glib_sys::g_variant_builder_unref(builder); + // HACK: This is to prevent C taking ownership + // of "floating" Variants, + // where Rust gets to keep a stale reference + // and crash when trying to drop it. + glib_sys::g_variant_ref_sink(ret); glib::Variant::from_glib_full(ret) } } @@ -141,7 +146,7 @@ fn set_layout(kind: String, name: String) { .chain(inputs).collect(); settings.set_value( "sources", - &variants::ArrayPairString(inputs).to_variant() + &variants::ArrayPairString(inputs).to_variant(), ); settings.apply(); }