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.
This commit is contained in:
		@ -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();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user