From de298130aa3507b7f9fb0947dcce3867d3e65388 Mon Sep 17 00:00:00 2001 From: chrysos349 Date: Tue, 5 Mar 2024 10:12:44 +0300 Subject: [PATCH] gnome-connections: update to 45.0 --- ...-crashes-in-frdp-channel-clipboard-c.patch | 350 ++++++++++++++++++ srcpkgs/gnome-connections/template | 8 +- 2 files changed, 354 insertions(+), 4 deletions(-) create mode 100644 srcpkgs/gnome-connections/patches/fix-crashes-in-frdp-channel-clipboard-c.patch diff --git a/srcpkgs/gnome-connections/patches/fix-crashes-in-frdp-channel-clipboard-c.patch b/srcpkgs/gnome-connections/patches/fix-crashes-in-frdp-channel-clipboard-c.patch new file mode 100644 index 00000000000000..6dd29f6bca9561 --- /dev/null +++ b/srcpkgs/gnome-connections/patches/fix-crashes-in-frdp-channel-clipboard-c.patch @@ -0,0 +1,350 @@ +this patch fixes several crashes related to clipboard channel in gtk-frdp subproject +(backported from 46.beta) + +diff --git a/subprojects/gtk-frdp/src/frdp-channel-clipboard.c b/subprojects/gtk-frdp/src/frdp-channel-clipboard.c +index 918b4709e..f7f376388 100644 +--- a/subprojects/gtk-frdp/src/frdp-channel-clipboard.c ++++ b/subprojects/gtk-frdp/src/frdp-channel-clipboard.c +@@ -58,6 +58,13 @@ typedef struct + FILEDESCRIPTORW *descriptor; + } FrdpLocalFileInfo; + ++typedef struct ++{ ++ guint clip_data_id; ++ gsize local_files_count; ++ FrdpLocalFileInfo *local_files_infos; ++} FrdpLocalLockData; ++ + typedef struct _FrdpRemoteFileInfo FrdpRemoteFileInfo; + + struct _FrdpRemoteFileInfo +@@ -108,6 +115,14 @@ typedef struct + GMutex fuse_mutex; + + fuse_ino_t current_inode; ++ ++ GList *locked_data; /* List of locked arrays of files - list of (FrdpLocalLockData *) */ ++ GMutex lock_mutex; ++ gboolean pending_lock; /* Lock was requested right after format list has been sent */ ++ guint pending_lock_id; /* Id for the pending lock */ ++ gboolean awaiting_data_request; /* Format list has been send but data were not requested yet */ ++ ++ guint remote_clip_data_id; /* clipDataId for copying from remote side */ + } FrdpChannelClipboardPrivate; + + G_DEFINE_TYPE_WITH_PRIVATE (FrdpChannelClipboard, frdp_channel_clipboard, FRDP_TYPE_CHANNEL) +@@ -129,6 +144,10 @@ static void clipboard_owner_change_cb (GtkClipboard *cl + GdkEventOwnerChange *event, + gpointer user_data); + ++static void frdp_local_lock_data_free (FrdpLocalLockData *lock_data); ++static void lock_current_local_files (FrdpChannelClipboard *self, ++ guint clip_data_id); ++ + static void + frdp_channel_clipboard_get_property (GObject *object, + guint property_id, +@@ -181,7 +200,15 @@ frdp_channel_clipboard_finalize (GObject *object) + _gtk_clipboard_clear_func (priv->gtk_clipboard, self); + g_clear_pointer (&priv->fuse_directory, g_free); + ++ g_mutex_lock (&priv->lock_mutex); ++ ++ g_list_free_full (priv->locked_data, (GDestroyNotify) frdp_local_lock_data_free); ++ priv->locked_data = NULL; ++ ++ g_mutex_unlock (&priv->lock_mutex); ++ + g_mutex_clear (&priv->fuse_mutex); ++ g_mutex_clear (&priv->lock_mutex); + + G_OBJECT_CLASS (frdp_channel_clipboard_parent_class)->finalize (object); + } +@@ -269,6 +296,8 @@ request_size (FrdpChannelClipboard *self, + file_contents_request.cbRequested = 8; + file_contents_request.nPositionHigh = 0; + file_contents_request.nPositionLow = 0; ++ file_contents_request.haveClipDataId = TRUE; ++ file_contents_request.clipDataId = priv->remote_clip_data_id; + + size_request = g_new0 (FrdpRemoteFileRequest, 1); + size_request->index = index; +@@ -435,7 +464,8 @@ fuse_read (fuse_req_t request, + file_contents_request.cbRequested = size; + file_contents_request.nPositionHigh = offset >> 32; + file_contents_request.nPositionLow = offset & 0xffffffff; +- file_contents_request.haveClipDataId = FALSE; ++ file_contents_request.haveClipDataId = TRUE; ++ file_contents_request.clipDataId = priv->remote_clip_data_id; + + data_request = g_new0 (FrdpRemoteFileRequest, 1); + data_request->index = index; +@@ -612,6 +642,9 @@ frdp_channel_clipboard_init (FrdpChannelClipboard *self) + priv->clipboard_owner_changed_id = g_signal_connect (priv->gtk_clipboard, "owner-change", G_CALLBACK (clipboard_owner_change_cb), self); + priv->fgdw_id = CB_FORMAT_TEXTURILIST; + priv->current_inode = FUSE_ROOT_ID + 1; ++ priv->locked_data = NULL; ++ priv->pending_lock = FALSE; ++ priv->remote_clip_data_id = 0; + + argv[0] = "gnome-connections"; + argv[1] = "-d"; +@@ -621,6 +654,7 @@ frdp_channel_clipboard_init (FrdpChannelClipboard *self) + priv->remote_files_requests = g_hash_table_new (g_direct_hash, g_direct_equal); + + g_mutex_init (&priv->fuse_mutex); ++ g_mutex_init (&priv->lock_mutex); + + priv->fuse_directory = g_mkdtemp (g_strdup_printf ("%s/clipboard-XXXXXX/", g_get_user_runtime_dir ())); + +@@ -669,6 +703,7 @@ send_client_capabilities (FrdpChannelClipboard *self) + general_capability_set.version = CB_CAPS_VERSION_2; + general_capability_set.generalFlags = CB_USE_LONG_FORMAT_NAMES | + CB_STREAM_FILECLIP_ENABLED | ++ CB_CAN_LOCK_CLIPDATA | + CB_FILECLIP_NO_FILE_PATHS | + CB_HUGE_FILE_SUPPORT_ENABLED; + +@@ -727,6 +762,7 @@ send_client_format_list (FrdpChannelClipboard *self) + format_list.numFormats = j; + format_list.formats = formats; + ++ priv->awaiting_data_request = TRUE; + ret = priv->cliprdr_client_context->ClientFormatList (priv->cliprdr_client_context, &format_list); + + if (formats != NULL) { +@@ -886,12 +922,19 @@ _gtk_clipboard_get_func (GtkClipboard *clipboard, + guint info, + gpointer user_data) + { ++ CLIPRDR_LOCK_CLIPBOARD_DATA lock_clipboard_data = { 0 }; + FrdpChannelClipboard *self = (FrdpChannelClipboard *) user_data; + FrdpChannelClipboardPrivate *priv = frdp_channel_clipboard_get_instance_private (self); + FrdpClipboardRequest *current_request; + gchar *data = NULL; + gint length; + ++ lock_clipboard_data.msgType = CB_LOCK_CLIPDATA; ++ lock_clipboard_data.msgFlags = 0; ++ lock_clipboard_data.dataLen = 4; ++ lock_clipboard_data.clipDataId = ++priv->remote_clip_data_id; ++ priv->cliprdr_client_context->ClientLockClipboardData (priv->cliprdr_client_context, &lock_clipboard_data); ++ + current_request = frdp_clipboard_request_send (self, info); + if (current_request != NULL) { + +@@ -1051,9 +1094,10 @@ static void + _gtk_clipboard_clear_func (GtkClipboard *clipboard, + gpointer user_data) + { +- FrdpChannelClipboard *self = (FrdpChannelClipboard *) user_data; +- FrdpChannelClipboardPrivate *priv = frdp_channel_clipboard_get_instance_private (self); +- guint i; ++ CLIPRDR_UNLOCK_CLIPBOARD_DATA unlock_clipboard_data = { 0 }; ++ FrdpChannelClipboard *self = (FrdpChannelClipboard *) user_data; ++ FrdpChannelClipboardPrivate *priv = frdp_channel_clipboard_get_instance_private (self); ++ guint i; + + g_mutex_lock (&priv->fuse_mutex); + +@@ -1070,6 +1114,12 @@ _gtk_clipboard_clear_func (GtkClipboard *clipboard, + + g_mutex_unlock (&priv->fuse_mutex); + ++ unlock_clipboard_data.msgType = CB_UNLOCK_CLIPDATA; ++ unlock_clipboard_data.msgFlags = 0; ++ unlock_clipboard_data.dataLen = 4; ++ unlock_clipboard_data.clipDataId = priv->remote_clip_data_id; ++ priv->cliprdr_client_context->ClientUnlockClipboardData (priv->cliprdr_client_context, &unlock_clipboard_data); ++ + clear_local_files_infos (self); + + priv->remote_data_in_clipboard = FALSE; +@@ -1373,6 +1423,12 @@ clipboard_content_received (GtkClipboard *clipboard, + } + g_list_free_full (list, g_free); + ++ if (priv->awaiting_data_request && priv->pending_lock) { ++ lock_current_local_files (self, priv->pending_lock_id); ++ ++ priv->awaiting_data_request = FALSE; ++ } ++ + send_data_response (self, data, priv->local_files_count * sizeof (FILEDESCRIPTORW) + 4); + } + } else { +@@ -1481,22 +1537,50 @@ server_file_contents_request (CliprdrClientContext *context, + FrdpChannelClipboard *self = (FrdpChannelClipboard *) context->custom; + FrdpChannelClipboardPrivate *priv = frdp_channel_clipboard_get_instance_private (self); + CLIPRDR_FILE_CONTENTS_RESPONSE response = { 0 }; ++ FrdpLocalFileInfo local_file_info; ++ FrdpLocalLockData *ldata; + GFileInputStream *stream; + GFileInfo *file_info; + GFileType file_type; ++ gboolean local_file_info_set = FALSE, clip_data_id_found = FALSE; + guint64 *size; + goffset offset; + guchar *data = NULL; + gssize bytes_read; ++ GList *iter; + GFile *file; + + response.msgType = CB_FILECONTENTS_RESPONSE; + response.msgFlags = CB_RESPONSE_FAIL; + response.streamId = file_contents_request->streamId; + ++ g_mutex_lock (&priv->lock_mutex); ++ ++ if (file_contents_request->haveClipDataId) { ++ for (iter = priv->locked_data; iter != NULL; iter = iter->next) { ++ ldata = (FrdpLocalLockData *) iter->data; ++ ++ if (ldata->clip_data_id == file_contents_request->clipDataId) { ++ clip_data_id_found = TRUE; ++ if (file_contents_request->listIndex < ldata->local_files_count) { ++ local_file_info = ldata->local_files_infos[file_contents_request->listIndex]; ++ local_file_info_set = TRUE; ++ } ++ break; ++ } ++ } ++ } ++ ++ if (!local_file_info_set && !clip_data_id_found) { ++ if (file_contents_request->listIndex < priv->local_files_count) { ++ local_file_info = priv->local_files_infos[file_contents_request->listIndex]; ++ local_file_info_set = TRUE; ++ } ++ } ++ + /* TODO: Make it async. Signal progress if FD_SHOWPROGRESSUI is present. */ +- if (file_contents_request->listIndex < priv->local_files_count) { +- file = g_file_new_for_uri (priv->local_files_infos[file_contents_request->listIndex].uri); ++ if (local_file_info_set) { ++ file = g_file_new_for_uri (local_file_info.uri); + + if (file_contents_request->dwFlags & FILECONTENTS_SIZE) { + file_info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_SIZE, G_FILE_QUERY_INFO_NONE, NULL, NULL); +@@ -1540,6 +1624,8 @@ server_file_contents_request (CliprdrClientContext *context, + g_warning ("Requested index is outside of the file list!"); + } + ++ g_mutex_unlock (&priv->lock_mutex); ++ + return priv->cliprdr_client_context->ClientFileContentsResponse (priv->cliprdr_client_context, &response); + } + +@@ -1597,11 +1683,99 @@ server_file_contents_response (CliprdrClientContext *context, + g_free (request); + g_mutex_unlock (&priv->fuse_mutex); + } ++ } else { ++ if (file_contents_response->msgFlags & CB_RESPONSE_FAIL) { ++ g_warning ("Server file response has failed!"); ++ } + } + + return CHANNEL_RC_OK; + } + ++static void ++lock_current_local_files (FrdpChannelClipboard *self, ++ guint clip_data_id) ++{ ++ FrdpChannelClipboardPrivate *priv = frdp_channel_clipboard_get_instance_private (self); ++ FrdpLocalLockData *lock_data; ++ guint i; ++ ++ g_mutex_lock (&priv->lock_mutex); ++ ++ /* TODO: Implement flock */ ++ if (priv->local_files_count > 0) { ++ lock_data = g_new (FrdpLocalLockData, 1); ++ lock_data->clip_data_id = clip_data_id; ++ lock_data->local_files_count = priv->local_files_count; ++ lock_data->local_files_infos = g_new (FrdpLocalFileInfo, lock_data->local_files_count); ++ for (i = 0; i < lock_data->local_files_count; i++) { ++ lock_data->local_files_infos[i].descriptor = priv->local_files_infos[i].descriptor; ++ lock_data->local_files_infos[i].uri = g_strdup (priv->local_files_infos[i].uri); ++ } ++ ++ priv->locked_data = g_list_append (priv->locked_data, lock_data); ++ if (priv->pending_lock_id == clip_data_id) ++ priv->pending_lock = FALSE; ++ } ++ ++ g_mutex_unlock (&priv->lock_mutex); ++} ++ ++static guint ++server_lock_clipboard_data (CliprdrClientContext *context, ++ const CLIPRDR_LOCK_CLIPBOARD_DATA *lock_clipboard_data) ++{ ++ FrdpChannelClipboard *self = (FrdpChannelClipboard *) context->custom; ++ FrdpChannelClipboardPrivate *priv = frdp_channel_clipboard_get_instance_private (self); ++ ++ if (priv->awaiting_data_request) { ++ priv->pending_lock = TRUE; ++ priv->pending_lock_id = lock_clipboard_data->clipDataId; ++ } else { ++ lock_current_local_files (self, lock_clipboard_data->clipDataId); ++ } ++ ++ return CHANNEL_RC_OK; ++} ++ ++static void ++frdp_local_lock_data_free (FrdpLocalLockData *lock_data) ++{ ++ guint i; ++ ++ for (i = 0; i < lock_data->local_files_count; i++) ++ g_free (lock_data->local_files_infos[i].uri); ++ g_free (lock_data->local_files_infos); ++ g_free (lock_data); ++} ++ ++static guint ++server_unlock_clipboard_data (CliprdrClientContext *context, ++ const CLIPRDR_UNLOCK_CLIPBOARD_DATA *unlock_clipboard_data) ++{ ++ FrdpChannelClipboard *self = (FrdpChannelClipboard *) context->custom; ++ FrdpChannelClipboardPrivate *priv = frdp_channel_clipboard_get_instance_private (self); ++ FrdpLocalLockData *lock_data; ++ GList *iter; ++ ++ g_mutex_lock (&priv->lock_mutex); ++ ++ for (iter = priv->locked_data; iter != NULL; iter = iter->next) { ++ lock_data = iter->data; ++ ++ if (lock_data->clip_data_id == unlock_clipboard_data->clipDataId) { ++ frdp_local_lock_data_free (lock_data); ++ ++ priv->locked_data = g_list_delete_link (priv->locked_data, iter); ++ break; ++ } ++ } ++ ++ g_mutex_unlock (&priv->lock_mutex); ++ ++ return CHANNEL_RC_OK; ++} ++ + static void + frdp_channel_clipboard_set_client_context (FrdpChannelClipboard *self, + CliprdrClientContext *context) +@@ -1620,8 +1794,7 @@ frdp_channel_clipboard_set_client_context (FrdpChannelClipboard *self, + context->ServerFileContentsRequest = server_file_contents_request; + context->ServerFileContentsResponse = server_file_contents_response; + +- /* TODO: Implement these: +- pcCliprdrServerLockClipboardData ServerLockClipboardData; +- pcCliprdrServerUnlockClipboardData ServerUnlockClipboardData; +- */ ++ /* These don't lock/unlock files currently but store lists of files with their clipDataId. */ ++ context->ServerLockClipboardData = server_lock_clipboard_data; ++ context->ServerUnlockClipboardData = server_unlock_clipboard_data; + } diff --git a/srcpkgs/gnome-connections/template b/srcpkgs/gnome-connections/template index dd9245bf96b3a8..6ee939a1f1ba08 100644 --- a/srcpkgs/gnome-connections/template +++ b/srcpkgs/gnome-connections/template @@ -1,16 +1,16 @@ # Template file for 'gnome-connections' pkgname=gnome-connections -version=44.0 +version=45.0 revision=1 build_style=meson build_helper="gir" hostmakedepends="pkg-config gettext itstool vala desktop-file-utils glib-devel" makedepends="gtk+3-devel libhandy1-devel gtk-vnc-devel libgcrypt-devel - gnutls-devel libsasl-devel libsecret-devel freerdp-devel" + gnutls-devel libsasl-devel libsecret-devel freerdp-devel fuse3-devel" short_desc="Remote desktop client for the GNOME desktop environment" maintainer="oreo6391 " license="GPL-3.0-or-later" homepage="https://gitlab.gnome.org/GNOME/connections/" -changelog="https://gitlab.gnome.org/GNOME/connections/-/raw/gnome-44/NEWS" +changelog="https://gitlab.gnome.org/GNOME/connections/-/raw/gnome-45/NEWS" distfiles="${GNOME_SITE}/gnome-connections/${version%.*}/gnome-connections-${version}.tar.xz" -checksum=34c7a6bbfec9a9acfa9c2d2dba4b251431cd71874f8f055c5ff26f26f4244199 +checksum=b9fab525b90a3e27d113c16fb868c2b9c47bf8149310d14db862ea1912c06fb8