diff options
author | Christoph Reiter <creiter@src.gnome.org> | 2017-06-02 12:55:23 +0200 |
---|---|---|
committer | Christoph Reiter <creiter@src.gnome.org> | 2017-06-02 13:22:36 +0200 |
commit | a1dc9e466066dd18592559d21d8647a43169e73a (patch) | |
tree | 5fe1d760e262fab300bdd5647d32a1e5415f2fe8 /gtk/gtkfilechoosernativewin32.c | |
parent | ee408d5f75756375b8cb62ea742d967764754b20 (diff) | |
download | gtk+-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.c | 41 |
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); } } |