From b4c6759b4560811d7ade7a1095c113923699d951 Mon Sep 17 00:00:00 2001 From: Tony Gies Date: Wed, 4 Feb 2026 05:58:09 -0600 Subject: [PATCH] copy: fix file concatenation when invoked via COMMAND /C The COPY command with file concatenation (e.g., `copy /b a+b dest`) fails with "Source and destination cannot match" when invoked via `COMMAND /C`, such as when nmake executes makefile commands. Root cause: The /C handler builds cmd_line by concatenating argv elements with spaces, always adding a trailing space after the last argument. In expand_pluses(), `strrchr(cmd_args, ' ')` then finds this trailing space instead of the space before the destination filename, causing the destination to be effectively empty. Example with trailing space from /C: Input: "/b msload.com+msbio.cl1 io.sys " last_arg = strrchr(..., ' ') -> points to trailing " " Output: "/b msload.com ;msbio.cl1 io.sys " Result: first file group has no destination, defaults to source This bug was introduced in commit 234e221 ("copy: support any amount of pluses [fixes #94]"). The previous implementation was immune to trailing spaces because it used forward-searching (strchr from after the +) rather than backward-searching (strrchr from end of string). Fix: Strip trailing spaces from cmd_args_bkp before finding last_arg. --- src/command.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/command.c b/src/command.c index e1442b0..2298d58 100644 --- a/src/command.c +++ b/src/command.c @@ -2162,7 +2162,12 @@ static int expand_pluses(void) int len; char *p, *p2, *last_arg; + if (!strchr(cmd_args, '+')) + return 0; strcpy(cmd_args_bkp, cmd_args); + len = strlen(cmd_args_bkp); + while (len > 0 && cmd_args_bkp[len-1] == ' ') + cmd_args_bkp[--len] = '\0'; last_arg = strrchr(cmd_args_bkp, ' '); if (!last_arg) {