| https://savannah.gnu.org/bugs/?23922 |
| |
| From 6f3684710a0f832533191f8657a57bc2fbba90ba Mon Sep 17 00:00:00 2001 |
| From: eliz <eliz> |
| Date: Sat, 7 May 2011 08:29:13 +0000 |
| Subject: [PATCH] job.c (construct_command_argv_internal): Don't assume |
| shellflags is always non-NULL. Escape-protect characters |
| special to the shell when copying the value of SHELL into |
| new_line. Fixes Savannah bug #23922. |
| |
| --- |
| ChangeLog | 7 +++++++ |
| job.c | 23 ++++++++++++++++------- |
| 2 files changed, 23 insertions(+), 7 deletions(-) |
| |
| diff --git a/job.c b/job.c |
| index 67b402d..c2ce84d 100644 |
| --- a/job.c |
| +++ b/job.c |
| @@ -2844,12 +2844,12 @@ construct_command_argv_internal (char *line, char **restp, char *shell, |
| |
| unsigned int shell_len = strlen (shell); |
| unsigned int line_len = strlen (line); |
| - unsigned int sflags_len = strlen (shellflags); |
| + unsigned int sflags_len = shellflags ? strlen (shellflags) : 0; |
| char *command_ptr = NULL; /* used for batch_mode_shell mode */ |
| char *new_line; |
| |
| # ifdef __EMX__ /* is this necessary? */ |
| - if (!unixy_shell) |
| + if (!unixy_shell && shellflags) |
| shellflags[0] = '/'; /* "/c" */ |
| # endif |
| |
| @@ -2911,19 +2911,28 @@ construct_command_argv_internal (char *line, char **restp, char *shell, |
| |
| new_argv = xmalloc (4 * sizeof (char *)); |
| new_argv[0] = xstrdup(shell); |
| - new_argv[1] = xstrdup(shellflags); |
| + new_argv[1] = xstrdup(shellflags ? shellflags : ""); |
| new_argv[2] = line; |
| new_argv[3] = NULL; |
| return new_argv; |
| } |
| |
| - new_line = alloca (shell_len + 1 + sflags_len + 1 |
| + new_line = alloca ((shell_len*2) + 1 + sflags_len + 1 |
| + (line_len*2) + 1); |
| ap = new_line; |
| - memcpy (ap, shell, shell_len); |
| - ap += shell_len; |
| + /* Copy SHELL, escaping any characters special to the shell. If |
| + we don't escape them, construct_command_argv_internal will |
| + recursively call itself ad nauseam, or until stack overflow, |
| + whichever happens first. */ |
| + for (p = shell; *p != '\0'; ++p) |
| + { |
| + if (strchr (sh_chars, *p) != 0) |
| + *(ap++) = '\\'; |
| + *(ap++) = *p; |
| + } |
| *(ap++) = ' '; |
| - memcpy (ap, shellflags, sflags_len); |
| + if (shellflags) |
| + memcpy (ap, shellflags, sflags_len); |
| ap += sflags_len; |
| *(ap++) = ' '; |
| command_ptr = ap; |
| -- |
| 1.7.12 |
| |