[gnome-remote-desktop] clipboard-rdp: Don't add duplicated mime types to mime type tables



commit a9a3e331fa90ac6ec1446e6eecccbda741fa10c9
Author: Pascal Nowack <Pascal Nowack gmx de>
Date:   Wed Aug 11 11:37:43 2021 +0200

    clipboard-rdp: Don't add duplicated mime types to mime type tables
    
    Normally, all FormatLists contain all announced formats only once.
    With xfreerdp3, this is not the case any more, since the introduction
    of server to client file transfer via the clipboard for xfreerdp.
    Since file lists are announced via the name "FileGroupDescriptorW" and
    their id is dynamically assigned, gnome-remote-desktop replaces the
    existing mime type tables of their mime type.
    
    The problem with duplicated mime types is, that gnome-remote-desktop
    correctly replaces the old mime type tables, if they exist, but for
    each freed mime type table still tries to announce them to mutter.
    glib realizes this situation, when creating the string variant for each
    type and emits a critical warning (instead of crashing).
    
    To solve this situation, use a GHashTable to ensure that mime type
    tables are only added once.
    Once all mime type tables are in the list, destroy the temporary hash
    table.
    With this handling, gnome-remote-desktop ignores all duplicated entries
    in a FormatList and only picks their first occurrence.

 src/grd-clipboard-rdp.c | 48 +++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 37 insertions(+), 11 deletions(-)
---
diff --git a/src/grd-clipboard-rdp.c b/src/grd-clipboard-rdp.c
index 95f3418..2b5f30c 100644
--- a/src/grd-clipboard-rdp.c
+++ b/src/grd-clipboard-rdp.c
@@ -1161,6 +1161,7 @@ cliprdr_client_format_list (CliprdrServerContext      *cliprdr_context,
 {
   GrdClipboardRdp *clipboard_rdp = cliprdr_context->custom;
   ServerFormatListUpdateContext *update_context;
+  GHashTable *found_mime_types;
   GrdMimeTypeTable *mime_type_table = NULL;
   GList *mime_type_tables = NULL;
   GrdMimeType mime_type;
@@ -1168,6 +1169,8 @@ cliprdr_client_format_list (CliprdrServerContext      *cliprdr_context,
   HANDLE events[2];
   uint32_t i;
 
+  found_mime_types = g_hash_table_new (NULL, NULL);
+
   /**
    * The text format CF_TEXT can depend on the CF_LOCALE content. In such
    * situations, we might not get the correct content from WinPR.
@@ -1186,6 +1189,7 @@ cliprdr_client_format_list (CliprdrServerContext      *cliprdr_context,
           mime_type_table->rdp.format_id = format_list->formats[i].formatId;
           mime_type_tables = g_list_append (mime_type_tables, mime_type_table);
 
+          g_hash_table_add (found_mime_types, GUINT_TO_POINTER (mime_type));
           mime_type = GRD_MIME_TYPE_TEXT_UTF8_STRING;
 
           mime_type_table = g_malloc0 (sizeof (GrdMimeTypeTable));
@@ -1193,6 +1197,7 @@ cliprdr_client_format_list (CliprdrServerContext      *cliprdr_context,
           mime_type_table->rdp.format_id = format_list->formats[i].formatId;
           mime_type_tables = g_list_append (mime_type_tables, mime_type_table);
 
+          g_hash_table_add (found_mime_types, GUINT_TO_POINTER (mime_type));
           already_has_text_format = TRUE;
           g_debug ("[RDP.CLIPRDR] Force using CF_UNICODETEXT over CF_TEXT as "
                    "external format for text/plain;charset=utf-8 and UTF8_STRING");
@@ -1215,16 +1220,22 @@ cliprdr_client_format_list (CliprdrServerContext      *cliprdr_context,
           (strcmp (format_list->formats[i].formatName, "FileGroupDescriptorW") == 0 ||
            strcmp (format_list->formats[i].formatName, "FileGroupDescri") == 0))
         {
-          /**
-           * Advertise the "x-special/gnome-copied-files" format in addition to
-           * the "text/uri-list" format
-           */
-          mime_type = GRD_MIME_TYPE_XS_GNOME_COPIED_FILES;
-
-          mime_type_table = g_malloc0 (sizeof (GrdMimeTypeTable));
-          mime_type_table->mime_type = mime_type;
-          mime_type_table->rdp.format_id = format_list->formats[i].formatId;
-          mime_type_tables = g_list_append (mime_type_tables, mime_type_table);
+          if (!g_hash_table_contains (found_mime_types,
+                                      GUINT_TO_POINTER (GRD_MIME_TYPE_TEXT_URILIST)))
+            {
+              /**
+               * Advertise the "x-special/gnome-copied-files" format in addition to
+               * the "text/uri-list" format
+               */
+              mime_type = GRD_MIME_TYPE_XS_GNOME_COPIED_FILES;
+
+              mime_type_table = g_malloc0 (sizeof (GrdMimeTypeTable));
+              mime_type_table->mime_type = mime_type;
+              mime_type_table->rdp.format_id = format_list->formats[i].formatId;
+              mime_type_tables = g_list_append (mime_type_tables, mime_type_table);
+
+              g_hash_table_add (found_mime_types, GUINT_TO_POINTER (mime_type));
+            }
 
           mime_type = GRD_MIME_TYPE_TEXT_URILIST;
         }
@@ -1244,11 +1255,15 @@ cliprdr_client_format_list (CliprdrServerContext      *cliprdr_context,
                 {
                   mime_type = GRD_MIME_TYPE_TEXT_PLAIN_UTF8;
 
+                  g_assert (!g_hash_table_contains (found_mime_types,
+                                                    GUINT_TO_POINTER (mime_type)));
+
                   mime_type_table = g_malloc0 (sizeof (GrdMimeTypeTable));
                   mime_type_table->mime_type = mime_type;
                   mime_type_table->rdp.format_id = format_list->formats[i].formatId;
                   mime_type_tables = g_list_append (mime_type_tables,
                                                     mime_type_table);
+                  g_hash_table_add (found_mime_types, GUINT_TO_POINTER (mime_type));
 
                   mime_type = GRD_MIME_TYPE_TEXT_UTF8_STRING;
                   already_has_text_format = TRUE;
@@ -1281,15 +1296,26 @@ cliprdr_client_format_list (CliprdrServerContext      *cliprdr_context,
             }
         }
 
-      if (mime_type != GRD_MIME_TYPE_NONE)
+      if (mime_type != GRD_MIME_TYPE_NONE &&
+          !g_hash_table_contains (found_mime_types, GUINT_TO_POINTER (mime_type)))
         {
           mime_type_table = g_malloc0 (sizeof (GrdMimeTypeTable));
           mime_type_table->mime_type = mime_type;
           mime_type_table->rdp.format_id = format_list->formats[i].formatId;
           mime_type_tables = g_list_append (mime_type_tables, mime_type_table);
+
+          g_hash_table_add (found_mime_types, GUINT_TO_POINTER (mime_type));
+        }
+      else if (mime_type != GRD_MIME_TYPE_NONE)
+        {
+          g_debug ("[RDP.CLIPRDR] Ignoring duplicated format: id: %u, name: %s",
+                   format_list->formats[i].formatId,
+                   format_list->formats[i].formatName);
         }
     }
 
+  g_hash_table_destroy (found_mime_types);
+
   if (clipboard_rdp->server_format_list_update_id)
     {
       g_debug ("[RDP.CLIPRDR] Wrong message sequence: Got new format list "


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]