diff options
author | Matthias Clasen <mclasen@redhat.com> | 2017-07-01 19:13:03 -0400 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2017-07-07 12:03:55 -0400 |
commit | 388078ba88561c64299fe892720452e679e00be3 (patch) | |
tree | 0d910ba0f4be093b7f05b1cb8d14d90548facffd /gtk/gtkfilechoosernativeportal.c | |
parent | 29ff3c072c61ce227a4b16840282293d74211a35 (diff) | |
download | gtk+-388078ba88561c64299fe892720452e679e00be3.tar.gz |
Avoid a race in the file chooser portal
Use the new predictable request object path and connect
to the Response signal before issuing the portal call.
This avoids a race that is pretty unlikely to hit in
the filechooser case.
Diffstat (limited to 'gtk/gtkfilechoosernativeportal.c')
-rw-r--r-- | gtk/gtkfilechoosernativeportal.c | 39 |
1 files changed, 36 insertions, 3 deletions
diff --git a/gtk/gtkfilechoosernativeportal.c b/gtk/gtkfilechoosernativeportal.c index bf29442d09..6f686e434c 100644 --- a/gtk/gtkfilechoosernativeportal.c +++ b/gtk/gtkfilechoosernativeportal.c @@ -180,6 +180,7 @@ open_file_msg_cb (GObject *source_object, GtkFileChooserNative *self = data->self; GDBusMessage *reply; GError *error = NULL; + g_autofree char *handle = NULL; reply = g_dbus_connection_send_message_with_reply_finish (data->connection, res, &error); @@ -197,8 +198,7 @@ open_file_msg_cb (GObject *source_object, return; } - g_variant_get_child (g_dbus_message_get_body (reply), 0, "o", - &data->portal_handle); + g_variant_get_child (g_dbus_message_get_body (reply), 0, "o", &handle); if (data->hidden) { @@ -207,8 +207,13 @@ open_file_msg_cb (GObject *source_object, filechooser_portal_data_free (data); self->mode_data = NULL; } - else + else if (strcmp (handle, data->portal_handle) != 0) { + g_free (data->portal_handle); + data->portal_handle = g_steal_pointer (&handle); + g_dbus_connection_signal_unsubscribe (data->connection, + data->portal_response_signal_id); + data->portal_response_signal_id = g_dbus_connection_signal_subscribe (data->connection, "org.freedesktop.portal.Desktop", @@ -289,14 +294,42 @@ show_portal_file_chooser (GtkFileChooserNative *self, GVariantBuilder opt_builder; gboolean multiple; const char *title; + char *token; + char *sender; + int i; message = g_dbus_message_new_method_call ("org.freedesktop.portal.Desktop", "/org/freedesktop/portal/desktop", "org.freedesktop.portal.FileChooser", data->method_name); + token = g_strdup_printf ("gtk%d", g_random_int_range (0, G_MAXINT)); + sender = g_strdup (g_dbus_connection_get_unique_name (data->connection) + 1); + for (i = 0; sender[i]; i++) + if (sender[i] == '.') + sender[i] = '_'; + + data->portal_handle = g_strdup_printf ("/org/fredesktop/portal/desktop/request/%s/%s", sender, token); + g_free (sender); + + data->portal_response_signal_id = + g_dbus_connection_signal_subscribe (data->connection, + "org.freedesktop.portal.Desktop", + "org.freedesktop.portal.Request", + "Response", + data->portal_handle, + NULL, + G_DBUS_SIGNAL_FLAGS_NO_MATCH_RULE, + response_cb, + self, NULL); + multiple = gtk_file_chooser_get_select_multiple (GTK_FILE_CHOOSER (self)); g_variant_builder_init (&opt_builder, G_VARIANT_TYPE_VARDICT); + + g_variant_builder_add (&opt_builder, "{sv}", "handle_token", + g_variant_new_string (token)); + g_free (token); + g_variant_builder_add (&opt_builder, "{sv}", "multiple", g_variant_new_boolean (multiple)); if (self->accept_label) |