summaryrefslogtreecommitdiff
path: root/src/w32fns.c
diff options
context:
space:
mode:
authorEli Zaretskii <eliz@gnu.org>2015-04-23 10:15:07 +0300
committerEli Zaretskii <eliz@gnu.org>2015-04-23 10:15:07 +0300
commitf2e2cd5969ddfb8d0302e2ee82986fa4a79b5b69 (patch)
tree31d151700baa5b044e3be7c744312e0c5a82af24 /src/w32fns.c
parent62fe329762301b4edf546e74893d9169906ffa96 (diff)
downloademacs-f2e2cd5969ddfb8d0302e2ee82986fa4a79b5b69.tar.gz
Avoid starting threads by w32-shell-execute
* src/w32fns.c (Fw32_shell_execute): Convert "file:///" URLs into local file names, before invoking ShellExecute. (Bug#20220)
Diffstat (limited to 'src/w32fns.c')
-rw-r--r--src/w32fns.c27
1 files changed, 26 insertions, 1 deletions
diff --git a/src/w32fns.c b/src/w32fns.c
index 6abb433fd2f..b9d7bd4d75b 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -29,6 +29,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <fcntl.h>
#include <unistd.h>
+#include <c-ctype.h>
+
#include "lisp.h"
#include "w32term.h"
#include "frame.h"
@@ -7038,7 +7040,28 @@ a ShowWindow flag:
#else /* !CYGWIN */
- current_dir = ENCODE_FILE (current_dir);
+ const char file_url_str[] = "file:///";
+ const int file_url_len = sizeof (file_url_str) - 1;
+ if (strncmp (SSDATA (document), file_url_str, file_url_len) == 0)
+ {
+ /* Passing "file:///" URLs to ShellExecute causes shlwapi.dll to
+ start a thread in some rare system configurations, for
+ unknown reasons. That thread is started in the context of
+ the Emacs process, but out of control of our code, and seems
+ to never exit afterwards. Each such thread reserves 8MB of
+ stack space (because that's the value recorded in the Emacs
+ executable at link time: Emacs needs a large stack). So a
+ large enough number of invocations of w32-shell-execute can
+ potentially cause the Emacs process to run out of available
+ address space, which is nasty. To work around this, we
+ convert such URLs to local file names, which seems to prevent
+ those threads from starting. See bug #20220. */
+ char *p = SSDATA (document) + file_url_len;
+
+ if (c_isalpha (*p) && p[1] == ':' && IS_DIRECTORY_SEP (p[2]))
+ document = Fsubstring_no_properties (document,
+ make_number (file_url_len), Qnil);
+ }
/* We have a situation here. If DOCUMENT is a relative file name,
but its name includes leading directories, i.e. it lives not in
CURRENT_DIR, but in its subdirectory, then ShellExecute below
@@ -7071,6 +7094,8 @@ a ShowWindow flag:
else
document = ENCODE_FILE (document);
UNGCPRO;
+
+ current_dir = ENCODE_FILE (current_dir);
if (use_unicode)
{
wchar_t document_w[MAX_PATH], current_dir_w[MAX_PATH];