Fix emacsclient --alternate-editor='' SIGSEGV

Problem reported by Ken Speegle (Bug#81716)
* lib-src/emacsclient.c (fail): Don’t get confused by trailing
whitepace in alternate_editor.  Quietly ignore alternate_editor
if it has no tokens (this part was suggested by Eli Zaretskii).
This commit is contained in:
Paul Eggert 2026-08-27 09:37:58 -07:00
parent 6fc331b587
commit 490cd601ea

View file

@ -743,34 +743,45 @@ fail (void)
ptrdiff_t toks = 0; ptrdiff_t toks = 0;
/* Unpack alternate_editor's space-separated tokens into new_argv. */ /* Unpack alternate_editor's space-separated tokens into new_argv. */
for (char *tok = s; tok != NULL && *tok != '\0';) for (char *tok = s;;)
{ {
/* Skip leading delimiters, and set separator, skipping any
opening quote. Break out of loop if no remaining tokens. */
while (*tok == ' ')
tok++;
if (!*tok)
break;
char sep = ' ';
if (*tok == '"')
{
tok++;
sep = '"';
}
/* Allocate new token. */ /* Allocate new token. */
++toks; ++toks;
new_argv = xrealloc (new_argv, new_argv = xrealloc (new_argv,
new_argv_size + toks * sizeof (char *)); new_argv_size + toks * sizeof (char *));
/* Skip leading delimiters, and set separator, skipping any
opening quote. */
size_t skip = strspn (tok, " \"");
tok += skip;
char sep = (skip > 0 && tok[-1] == '"') ? '"' : ' ';
/* Record start of token. */ /* Record start of token. */
new_argv[toks - 1] = tok; new_argv[toks - 1] = tok;
/* Find end of token and overwrite it with NUL. */ /* Find end of token and overwrite it with NUL. */
tok = strchr (tok, sep); tok = strchr (tok, sep);
if (tok != NULL) if (!tok)
*tok++ = '\0'; break;
*tok++ = '\0';
} }
/* Append main_argv arguments to new_argv. */ if (toks)
memcpy (&new_argv[toks], main_argv + optind, extra_args_size); {
/* Append main_argv arguments to new_argv. */
memcpy (&new_argv[toks], main_argv + optind, extra_args_size);
execvp (*new_argv, new_argv); execvp (*new_argv, new_argv);
message (true, "%s: error executing alternate editor \"%s\"\n", message (true, "%s: error executing alternate editor \"%s\"\n",
progname, alternate_editor); progname, alternate_editor);
}
} }
exit (EXIT_FAILURE); exit (EXIT_FAILURE);
} }