diff options
| author | Eli Zaretskii | 2015-07-30 19:50:51 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2015-07-30 19:50:51 +0300 |
| commit | f3f15aef9a2d79252ec061093c25160f29809976 (patch) | |
| tree | 2c309a0e9c153ff79a3f8a265decdd2712e8f003 /src | |
| parent | 91718f5f451aa99aaf9e4c48ecfc4d5c0535dc79 (diff) | |
| download | emacs-f3f15aef9a2d79252ec061093c25160f29809976.tar.gz emacs-f3f15aef9a2d79252ec061093c25160f29809976.zip | |
Support long URLs in w32-shell-execute
* src/w32fns.c (Fw32_shell_execute): Don't use filename_to_utf16
and filename_to_ansi to convert the DOCUMENT argument, as it could
be a URL that is not limited to MAX_PATH characters. Instead, use
MultiByteToWideChar directly, and allocate heap storage as
required to accommodate the converted string. Likewise with
non-Unicode operation. Ensure OPERATION is null-terminated, even
if it is longer than 32K bytes. (Bug#21158)
Diffstat (limited to 'src')
| -rw-r--r-- | src/w32.c | 2 | ||||
| -rw-r--r-- | src/w32.h | 1 | ||||
| -rw-r--r-- | src/w32fns.c | 28 |
3 files changed, 23 insertions, 8 deletions
| @@ -1490,7 +1490,7 @@ static int file_name_codepage; | |||
| 1490 | 1490 | ||
| 1491 | /* Produce a Windows ANSI codepage suitable for encoding file names. | 1491 | /* Produce a Windows ANSI codepage suitable for encoding file names. |
| 1492 | Return the information about that codepage in CP_INFO. */ | 1492 | Return the information about that codepage in CP_INFO. */ |
| 1493 | static int | 1493 | int |
| 1494 | codepage_for_filenames (CPINFO *cp_info) | 1494 | codepage_for_filenames (CPINFO *cp_info) |
| 1495 | { | 1495 | { |
| 1496 | /* A simple cache to avoid calling GetCPInfo every time we need to | 1496 | /* A simple cache to avoid calling GetCPInfo every time we need to |
| @@ -192,6 +192,7 @@ extern int filename_from_ansi (const char *, char *); | |||
| 192 | extern int filename_to_ansi (const char *, char *); | 192 | extern int filename_to_ansi (const char *, char *); |
| 193 | extern int filename_from_utf16 (const wchar_t *, char *); | 193 | extern int filename_from_utf16 (const wchar_t *, char *); |
| 194 | extern int filename_to_utf16 (const char *, wchar_t *); | 194 | extern int filename_to_utf16 (const char *, wchar_t *); |
| 195 | extern int codepage_for_filenames (CPINFO *); | ||
| 195 | extern Lisp_Object ansi_encode_filename (Lisp_Object); | 196 | extern Lisp_Object ansi_encode_filename (Lisp_Object); |
| 196 | extern int w32_copy_file (const char *, const char *, int, int, int); | 197 | extern int w32_copy_file (const char *, const char *, int, int, int); |
| 197 | 198 | ||
diff --git a/src/w32fns.c b/src/w32fns.c index 499450f4c92..c742ca8534f 100644 --- a/src/w32fns.c +++ b/src/w32fns.c | |||
| @@ -7090,6 +7090,8 @@ a ShowWindow flag: | |||
| 7090 | 7090 | ||
| 7091 | const char file_url_str[] = "file:///"; | 7091 | const char file_url_str[] = "file:///"; |
| 7092 | const int file_url_len = sizeof (file_url_str) - 1; | 7092 | const int file_url_len = sizeof (file_url_str) - 1; |
| 7093 | int doclen; | ||
| 7094 | |||
| 7093 | if (strncmp (SSDATA (document), file_url_str, file_url_len) == 0) | 7095 | if (strncmp (SSDATA (document), file_url_str, file_url_len) == 0) |
| 7094 | { | 7096 | { |
| 7095 | /* Passing "file:///" URLs to ShellExecute causes shlwapi.dll to | 7097 | /* Passing "file:///" URLs to ShellExecute causes shlwapi.dll to |
| @@ -7144,16 +7146,21 @@ a ShowWindow flag: | |||
| 7144 | UNGCPRO; | 7146 | UNGCPRO; |
| 7145 | 7147 | ||
| 7146 | current_dir = ENCODE_FILE (current_dir); | 7148 | current_dir = ENCODE_FILE (current_dir); |
| 7149 | /* Cannot use filename_to_utf16/ansi with DOCUMENT, since it could | ||
| 7150 | be a URL that is not limited to MAX_PATH chararcters. */ | ||
| 7151 | doclen = pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, | ||
| 7152 | SSDATA (document), -1, NULL, 0); | ||
| 7153 | doc_w = xmalloc (doclen * sizeof (wchar_t)); | ||
| 7154 | pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, | ||
| 7155 | SSDATA (document), -1, doc_w, doclen); | ||
| 7147 | if (use_unicode) | 7156 | if (use_unicode) |
| 7148 | { | 7157 | { |
| 7149 | wchar_t document_w[MAX_PATH], current_dir_w[MAX_PATH]; | 7158 | wchar_t current_dir_w[MAX_PATH]; |
| 7150 | SHELLEXECUTEINFOW shexinfo_w; | 7159 | SHELLEXECUTEINFOW shexinfo_w; |
| 7151 | 7160 | ||
| 7152 | /* Encode filename, current directory and parameters, and | 7161 | /* Encode the current directory and parameters, and convert |
| 7153 | convert operation to UTF-16. */ | 7162 | operation to UTF-16. */ |
| 7154 | filename_to_utf16 (SSDATA (current_dir), current_dir_w); | 7163 | filename_to_utf16 (SSDATA (current_dir), current_dir_w); |
| 7155 | filename_to_utf16 (SSDATA (document), document_w); | ||
| 7156 | doc_w = document_w; | ||
| 7157 | if (STRINGP (parameters)) | 7164 | if (STRINGP (parameters)) |
| 7158 | { | 7165 | { |
| 7159 | int len; | 7166 | int len; |
| @@ -7166,6 +7173,7 @@ a ShowWindow flag: | |||
| 7166 | params_w = alloca (len * sizeof (wchar_t)); | 7173 | params_w = alloca (len * sizeof (wchar_t)); |
| 7167 | pMultiByteToWideChar (CP_ACP, MB_ERR_INVALID_CHARS, | 7174 | pMultiByteToWideChar (CP_ACP, MB_ERR_INVALID_CHARS, |
| 7168 | SSDATA (parameters), -1, params_w, len); | 7175 | SSDATA (parameters), -1, params_w, len); |
| 7176 | params_w[len - 1] = 0; | ||
| 7169 | } | 7177 | } |
| 7170 | if (STRINGP (operation)) | 7178 | if (STRINGP (operation)) |
| 7171 | { | 7179 | { |
| @@ -7198,15 +7206,19 @@ a ShowWindow flag: | |||
| 7198 | shexinfo_w.nShow = | 7206 | shexinfo_w.nShow = |
| 7199 | (INTEGERP (show_flag) ? XINT (show_flag) : SW_SHOWDEFAULT); | 7207 | (INTEGERP (show_flag) ? XINT (show_flag) : SW_SHOWDEFAULT); |
| 7200 | success = ShellExecuteExW (&shexinfo_w); | 7208 | success = ShellExecuteExW (&shexinfo_w); |
| 7209 | xfree (doc_w); | ||
| 7201 | } | 7210 | } |
| 7202 | else | 7211 | else |
| 7203 | { | 7212 | { |
| 7204 | char document_a[MAX_PATH], current_dir_a[MAX_PATH]; | 7213 | char document_a[MAX_PATH], current_dir_a[MAX_PATH]; |
| 7205 | SHELLEXECUTEINFOA shexinfo_a; | 7214 | SHELLEXECUTEINFOA shexinfo_a; |
| 7215 | int codepage = codepage_for_filenames (NULL); | ||
| 7216 | int ldoc_a = pWideCharToMultiByte (codepage, 0, doc_w, -1, NULL, 0, | ||
| 7217 | NULL, NULL); | ||
| 7206 | 7218 | ||
| 7219 | doc_a = xmalloc (ldoc_a); | ||
| 7220 | pWideCharToMultiByte (codepage, 0, doc_w, -1, doc_a, ldoc_a, NULL, NULL); | ||
| 7207 | filename_to_ansi (SSDATA (current_dir), current_dir_a); | 7221 | filename_to_ansi (SSDATA (current_dir), current_dir_a); |
| 7208 | filename_to_ansi (SSDATA (document), document_a); | ||
| 7209 | doc_a = document_a; | ||
| 7210 | if (STRINGP (parameters)) | 7222 | if (STRINGP (parameters)) |
| 7211 | { | 7223 | { |
| 7212 | parameters = ENCODE_SYSTEM (parameters); | 7224 | parameters = ENCODE_SYSTEM (parameters); |
| @@ -7229,6 +7241,8 @@ a ShowWindow flag: | |||
| 7229 | shexinfo_a.nShow = | 7241 | shexinfo_a.nShow = |
| 7230 | (INTEGERP (show_flag) ? XINT (show_flag) : SW_SHOWDEFAULT); | 7242 | (INTEGERP (show_flag) ? XINT (show_flag) : SW_SHOWDEFAULT); |
| 7231 | success = ShellExecuteExA (&shexinfo_a); | 7243 | success = ShellExecuteExA (&shexinfo_a); |
| 7244 | xfree (doc_w); | ||
| 7245 | xfree (doc_a); | ||
| 7232 | } | 7246 | } |
| 7233 | 7247 | ||
| 7234 | if (success) | 7248 | if (success) |