From 1cbc21ad1101813ea7028a3679e77c141c36c306 Mon Sep 17 00:00:00 2001 From: Dorota Czaplejewicz Date: Mon, 3 Feb 2020 14:46:49 +0000 Subject: [PATCH 1/3] 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(); } From 2e9b8581e70a11e4f3936703f53d3cc36f1cea66 Mon Sep 17 00:00:00 2001 From: Dorota Czaplejewicz Date: Mon, 3 Feb 2020 14:49:54 +0000 Subject: [PATCH 2/3] variant: Fix leak --- eekboard/eekboard-context-service.c | 1 + 1 file changed, 1 insertion(+) diff --git a/eekboard/eekboard-context-service.c b/eekboard/eekboard-context-service.c index f74382be..c636c430 100644 --- a/eekboard/eekboard-context-service.c +++ b/eekboard/eekboard-context-service.c @@ -116,6 +116,7 @@ settings_get_layout(GSettings *settings, char **type, char **layout) GVariant *inputs = g_settings_get_value(settings, "sources"); // current layout is always first g_variant_get_child(inputs, 0, "(ss)", type, layout); + g_variant_unref(inputs); } void From b77051142268fde786110d5cb74c908a097e5b24 Mon Sep 17 00:00:00 2001 From: Dorota Czaplejewicz Date: Mon, 3 Feb 2020 14:59:14 +0000 Subject: [PATCH 3/3] keyboard_layout: Fix leak --- eekboard/eekboard-context-service.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/eekboard/eekboard-context-service.c b/eekboard/eekboard-context-service.c index c636c430..cf5e7e4d 100644 --- a/eekboard/eekboard-context-service.c +++ b/eekboard/eekboard-context-service.c @@ -140,9 +140,11 @@ eekboard_context_service_update_layout(EekboardContextService *context, enum squ switch (priv->purpose) { case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_NUMBER: case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_PHONE: + g_free(keyboard_layout); keyboard_layout = g_strdup("number"); break; case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_TERMINAL: + g_free(keyboard_layout); keyboard_layout = g_strdup("terminal"); break; default: