[gtk+/gtk-3-22] gtkfilechoosernativewin32: Fix support for non-ASCII paths



commit a2e2f38642b01a3b3bd1494a93d2bba23a75733a
Author: Christoph Reiter <creiter src gnome org>
Date:   Fri Jun 2 12:55:23 2017 +0200

    gtkfilechoosernativewin32: Fix support for non-ASCII paths
    
    The code used SIGDN_URL to get an URL for the selected item, but Windows URLs
    are a mix of unicode and percent encoded characters in the locale encoding
    and not something GFile can understand. The result is a garbage file
    path.
    
    Instead use SIGDN_FILESYSPATH to get a real file path if available.
    
    Also checks the return value of g_utf16_to_utf8 because file paths on
    Windows can contain lone surrogates which would make the conversion fail.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=783347

 gtk/gtkfilechoosernativewin32.c |   41 ++++++++++++++++++++++++++++++--------
 1 files changed, 32 insertions(+), 9 deletions(-)
---
diff --git a/gtk/gtkfilechoosernativewin32.c b/gtk/gtkfilechoosernativewin32.c
index 22411d3..9a1a3a2 100644
--- a/gtk/gtkfilechoosernativewin32.c
+++ b/gtk/gtkfilechoosernativewin32.c
@@ -342,22 +342,45 @@ filechooser_win32_thread_done (gpointer _data)
   return FALSE;
 }
 
+static GFile *
+get_file_for_shell_item (IShellItem *item)
+{
+  HRESULT hr;
+  PWSTR pathw = NULL;
+  char *path;
+  GFile *file;
+
+  hr = IShellItem_GetDisplayName (item, SIGDN_FILESYSPATH, &pathw);
+  if (SUCCEEDED (hr))
+    {
+      path = g_utf16_to_utf8 (pathw, -1, NULL, NULL, NULL);
+      CoTaskMemFree (pathw);
+      if (path != NULL)
+        {
+          file = g_file_new_for_path (path);
+          g_free (path);
+          return file;
+       }
+    }
+
+  /* TODO: also support URLs through SIGDN_URL, but Windows URLS are not
+   * RFC 3986 compliant and we'd need to convert them first.
+   */
+
+  return NULL;
+}
+
 static void
 data_add_shell_item (FilechooserWin32ThreadData *data,
                      IShellItem *item)
 {
-  HRESULT hr;
-  PWSTR urlw = NULL;
-  char *url;
+  GFile *file;
 
-  hr = IShellItem_GetDisplayName (item, SIGDN_URL, &urlw);
-  if (SUCCEEDED (hr))
+  file = get_file_for_shell_item (item);
+  if (file != NULL)
     {
-      url = g_utf16_to_utf8 (urlw, -1, NULL, NULL, NULL);
-      CoTaskMemFree (urlw);
-      data->files = g_slist_prepend (data->files, g_file_new_for_uri (url));
+      data->files = g_slist_prepend (data->files, file);
       data->response = GTK_RESPONSE_ACCEPT;
-      g_free (url);
     }
 }
 


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