summaryrefslogtreecommitdiff
path: root/gtk/gtkfilechoosernativewin32.c
diff options
context:
space:
mode:
authorChristoph Reiter <creiter@src.gnome.org>2017-06-02 12:55:23 +0200
committerChristoph Reiter <creiter@src.gnome.org>2017-06-02 13:22:36 +0200
commita1dc9e466066dd18592559d21d8647a43169e73a (patch)
tree5fe1d760e262fab300bdd5647d32a1e5415f2fe8 /gtk/gtkfilechoosernativewin32.c
parentee408d5f75756375b8cb62ea742d967764754b20 (diff)
downloadgtk+-a1dc9e466066dd18592559d21d8647a43169e73a.tar.gz
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
Diffstat (limited to 'gtk/gtkfilechoosernativewin32.c')
-rw-r--r--gtk/gtkfilechoosernativewin32.c41
1 files changed, 32 insertions, 9 deletions
diff --git a/gtk/gtkfilechoosernativewin32.c b/gtk/gtkfilechoosernativewin32.c
index 22411d35be..9a1a3a2c13 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);
}
}