Fix `--old-args` interaction with a daemon
authorWayne Davison <wayne@opencoder.net>
Tue, 18 Jan 2022 01:12:43 +0000 (17:12 -0800)
committerWayne Davison <wayne@opencoder.net>
Tue, 18 Jan 2022 02:11:03 +0000 (18:11 -0800)
Ensure that a remote rsync daemon will not split a filename arg unless
the user asked for `--old-args`.

clientserver.c
main.c

index 8e30f99f5b77cce90f3bb4bfef396fceb1b99f3a..66311d3ec81304aa31086a47e3cb17d528a8b3d8 100644 (file)
@@ -47,6 +47,7 @@ extern int protocol_version;
 extern int io_timeout;
 extern int no_detach;
 extern int write_batch;
+extern int old_style_args;
 extern int default_af_hint;
 extern int logfile_format_has_i;
 extern int logfile_format_has_o_or_i;
@@ -288,20 +289,45 @@ int start_inband_exchange(int f_in, int f_out, const char *user, int argc, char
 
        sargs[sargc++] = ".";
 
+       if (!old_style_args)
+               snprintf(line, sizeof line, " %.*s/", modlen, modname);
+
        while (argc > 0) {
                if (sargc >= MAX_ARGS - 1) {
                  arg_overflow:
                        rprintf(FERROR, "internal: args[] overflowed in do_cmd()\n");
                        exit_cleanup(RERR_SYNTAX);
                }
-               if (strncmp(*argv, modname, modlen) == 0
-                && argv[0][modlen] == '\0')
+               if (strncmp(*argv, modname, modlen) == 0 && argv[0][modlen] == '\0')
                        sargs[sargc++] = modname; /* we send "modname/" */
-               else if (**argv == '-') {
-                       if (asprintf(sargs + sargc++, "./%s", *argv) < 0)
-                               out_of_memory("start_inband_exchange");
-               } else
-                       sargs[sargc++] = *argv;
+               else {
+                       char *arg = *argv;
+                       int extra_chars = *arg == '-' ? 2 : 0; /* a leading dash needs a "./" prefix. */
+                       /* If --old-args was not specified, make sure that the arg won't split at a mod name! */
+                       if (!old_style_args && (p = strstr(arg, line)) != NULL) {
+                               do {
+                                       extra_chars += 2;
+                               } while ((p = strstr(p+1, line)) != NULL);
+                       }
+                       if (extra_chars) {
+                               char *f = arg;
+                               char *t = arg = new_array(char, strlen(arg) + extra_chars + 1);
+                               if (*f == '-') {
+                                       *t++ = '.';
+                                       *t++ = '/';
+                               }
+                               while (*f) {
+                                       if (*f == ' ' && strncmp(f, line, modlen+2) == 0) {
+                                               *t++ = '[';
+                                               *t++ = *f++;
+                                               *t++ = ']';
+                                       } else
+                                               *t++ = *f++;
+                               }
+                               *t = '\0';
+                       }
+                       sargs[sargc++] = arg;
+               }
                argv++;
                argc--;
        }
diff --git a/main.c b/main.c
index 31a28f51317325b7757885e989fe57ae110fc0c7..9019a9e9ecd015eb2928830fff6539f957ccbc90 100644 (file)
--- a/main.c
+++ b/main.c
@@ -477,7 +477,7 @@ static void show_malloc_stats(void)
 
 #define PRINT_ALLOC_NUM(title, descr, num) \
        rprintf(FINFO, "  %-11s%10" SIZE_T_FMT_MOD "d   (" descr ")\n", \
-              title ":", (SIZE_T_FMT_CAST)(num));
+               title ":", (SIZE_T_FMT_CAST)(num));
 
        PRINT_ALLOC_NUM("arena", "bytes from sbrk", mi.arena);
        PRINT_ALLOC_NUM("ordblks", "chunks not in use", mi.ordblks);