As POSIX recently pointed out[1], anything with semantics like system() or popen() should be passing "--" between "-c" and the user's string, in case the user intends to execute a utility beginning with '-' or '+'. POSIX recommends that users should not name files beginning with '-', but does not have a similar discouragement against files beginning with '+'. In particular, if your /bin/sh is bash, and you want to execute a script named "+O", this patch is essential. If you need to be portable to older m4, you can always prepend a space in your arguments to syscmd().
[1] https://www.austingroupbugs.net/view.php?id=1440 * src/builtin.c (m4_syscmd, m4_esyscmd): Pass "--" to sh prior to user's string. --- src/builtin.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/builtin.c b/src/builtin.c index 5e36ab35..576aebcb 100644 --- a/src/builtin.c +++ b/src/builtin.c @@ -947,7 +947,8 @@ m4_syscmd (struct obstack *obs MAYBE_UNUSED, int argc, token_data **argv) const char *cmd = ARG (1); int status; int sig_status; - const char *prog_args[4] = { "sh", "-c" }; + int slot = 3; + const char *prog_args[5] = { "sh", "-c", "--" }; if (bad_argc (argv[0], argc, 2, 2) || !*cmd) { /* The empty command is successful. */ @@ -961,9 +962,10 @@ m4_syscmd (struct obstack *obs MAYBE_UNUSED, int argc, token_data **argv) { prog_args[0] = "cmd"; prog_args[1] = "/c"; + slot = 2; } #endif - prog_args[2] = cmd; + prog_args[slot] = cmd; errno = 0; status = execute (ARG (0), SYSCMD_SHELL, prog_args, NULL, false, false, false, false, true, false, &sig_status); @@ -984,12 +986,13 @@ static void m4_esyscmd (struct obstack *obs, int argc, token_data **argv) { const char *cmd = ARG (1); - const char *prog_args[4] = { "sh", "-c" }; + const char *prog_args[5] = { "sh", "-c", "--" }; pid_t child; int fd; FILE *pin; int status; int sig_status; + int slot = 3; if (bad_argc (argv[0], argc, 2, 2) || !*cmd) { @@ -1004,9 +1007,10 @@ m4_esyscmd (struct obstack *obs, int argc, token_data **argv) { prog_args[0] = "cmd"; prog_args[1] = "/c"; + slot = 2; } #endif - prog_args[2] = cmd; + prog_args[slot] = cmd; errno = 0; child = create_pipe_in (ARG (0), SYSCMD_SHELL, prog_args, NULL, NULL, false, true, false, &fd); -- 2.33.1 _______________________________________________ M4-patches mailing list [email protected] https://lists.gnu.org/mailman/listinfo/m4-patches
