emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] master f3f15ae: Support long URLs in w32-shell-execute


From: Eli Zaretskii
Subject: [Emacs-diffs] master f3f15ae: Support long URLs in w32-shell-execute
Date: Thu, 30 Jul 2015 16:51:57 +0000

branch: master
commit f3f15aef9a2d79252ec061093c25160f29809976
Author: Eli Zaretskii <address@hidden>
Commit: Eli Zaretskii <address@hidden>

    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)
---
 src/w32.c    |    2 +-
 src/w32.h    |    1 +
 src/w32fns.c |   28 +++++++++++++++++++++-------
 3 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/src/w32.c b/src/w32.c
index 8721ed9..296729a 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -1490,7 +1490,7 @@ static int file_name_codepage;
 
 /* Produce a Windows ANSI codepage suitable for encoding file names.
    Return the information about that codepage in CP_INFO.  */
-static int
+int
 codepage_for_filenames (CPINFO *cp_info)
 {
   /* A simple cache to avoid calling GetCPInfo every time we need to
diff --git a/src/w32.h b/src/w32.h
index e62b93c..338cb06 100644
--- a/src/w32.h
+++ b/src/w32.h
@@ -192,6 +192,7 @@ extern int  filename_from_ansi (const char *, char *);
 extern int  filename_to_ansi (const char *, char *);
 extern int  filename_from_utf16 (const wchar_t *, char *);
 extern int  filename_to_utf16 (const char *, wchar_t *);
+extern int  codepage_for_filenames (CPINFO *);
 extern Lisp_Object ansi_encode_filename (Lisp_Object);
 extern int  w32_copy_file (const char *, const char *, int, int, int);
 
diff --git a/src/w32fns.c b/src/w32fns.c
index 499450f..c742ca8 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -7090,6 +7090,8 @@ a ShowWindow flag:
 
   const char file_url_str[] = "file:///";
   const int file_url_len = sizeof (file_url_str) - 1;
+  int doclen;
+
   if (strncmp (SSDATA (document), file_url_str, file_url_len) == 0)
     {
       /* Passing "file:///" URLs to ShellExecute causes shlwapi.dll to
@@ -7144,16 +7146,21 @@ a ShowWindow flag:
   UNGCPRO;
 
   current_dir = ENCODE_FILE (current_dir);
+  /* Cannot use filename_to_utf16/ansi with DOCUMENT, since it could
+     be a URL that is not limited to MAX_PATH chararcters.  */
+  doclen = pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS,
+                                SSDATA (document), -1, NULL, 0);
+  doc_w = xmalloc (doclen * sizeof (wchar_t));
+  pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS,
+                       SSDATA (document), -1, doc_w, doclen);
   if (use_unicode)
     {
-      wchar_t document_w[MAX_PATH], current_dir_w[MAX_PATH];
+      wchar_t current_dir_w[MAX_PATH];
       SHELLEXECUTEINFOW shexinfo_w;
 
-      /* Encode filename, current directory and parameters, and
-        convert operation to UTF-16.  */
+      /* Encode the current directory and parameters, and convert
+        operation to UTF-16.  */
       filename_to_utf16 (SSDATA (current_dir), current_dir_w);
-      filename_to_utf16 (SSDATA (document), document_w);
-      doc_w = document_w;
       if (STRINGP (parameters))
        {
          int len;
@@ -7166,6 +7173,7 @@ a ShowWindow flag:
          params_w = alloca (len * sizeof (wchar_t));
          pMultiByteToWideChar (CP_ACP, MB_ERR_INVALID_CHARS,
                                SSDATA (parameters), -1, params_w, len);
+         params_w[len - 1] = 0;
        }
       if (STRINGP (operation))
        {
@@ -7198,15 +7206,19 @@ a ShowWindow flag:
       shexinfo_w.nShow =
        (INTEGERP (show_flag) ? XINT (show_flag) : SW_SHOWDEFAULT);
       success = ShellExecuteExW (&shexinfo_w);
+      xfree (doc_w);
     }
   else
     {
       char document_a[MAX_PATH], current_dir_a[MAX_PATH];
       SHELLEXECUTEINFOA shexinfo_a;
+      int codepage = codepage_for_filenames (NULL);
+      int ldoc_a = pWideCharToMultiByte (codepage, 0, doc_w, -1, NULL, 0,
+                                        NULL, NULL);
 
+      doc_a = xmalloc (ldoc_a);
+      pWideCharToMultiByte (codepage, 0, doc_w, -1, doc_a, ldoc_a, NULL, NULL);
       filename_to_ansi (SSDATA (current_dir), current_dir_a);
-      filename_to_ansi (SSDATA (document), document_a);
-      doc_a = document_a;
       if (STRINGP (parameters))
        {
          parameters = ENCODE_SYSTEM (parameters);
@@ -7229,6 +7241,8 @@ a ShowWindow flag:
       shexinfo_a.nShow =
        (INTEGERP (show_flag) ? XINT (show_flag) : SW_SHOWDEFAULT);
       success = ShellExecuteExA (&shexinfo_a);
+      xfree (doc_w);
+      xfree (doc_a);
     }
 
   if (success)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]