]> git.ipfire.org Git - thirdparty/rsync.git/commitdiff
Handle files-from args that span 2 buffers.
authorWayne Davison <wayne@opencoder.net>
Tue, 9 Aug 2022 04:18:10 +0000 (21:18 -0700)
committerWayne Davison <wayne@opencoder.net>
Tue, 9 Aug 2022 04:18:10 +0000 (21:18 -0700)
exclude.c
io.c

index d811dd1fd1dcab4df28ed8b2adaa39e1e5ccb1c9..2394023fbd544c3dc8be777f94c3e1d8676be56f 100644 (file)
--- a/exclude.c
+++ b/exclude.c
@@ -349,6 +349,28 @@ static void maybe_add_literal_brackets_rule(filter_rule const *based_on, int arg
        }
 }
 
+static char *partial_string_buf = NULL;
+static int partial_string_len = 0;
+void implied_include_partial_string(const char *s_start, const char *s_end)
+{
+       partial_string_len = s_end - s_start;
+       if (partial_string_len <= 0 || partial_string_len >= MAXPATHLEN) { /* too-large should be impossible... */
+               partial_string_len = 0;
+               return;
+       }
+       if (!partial_string_buf)
+               partial_string_buf = new_array(char, MAXPATHLEN);
+       memcpy(partial_string_buf, s_start, partial_string_len);
+}
+
+void free_implied_include_partial_string()
+{
+       if (partial_string_buf) {
+               free(partial_string_buf);
+               partial_string_buf = NULL;
+       }
+}
+
 /* Each arg the client sends to the remote sender turns into an implied include
  * that the receiver uses to validate the file list from the sender. */
 void add_implied_include(const char *arg)
@@ -360,6 +382,14 @@ void add_implied_include(const char *arg)
        char *p;
        if (am_server || old_style_args || list_only || read_batch || filesfrom_host != NULL)
                return;
+       if (partial_string_len) {
+               arg_len = strlen(arg);
+               if (partial_string_len + arg_len >= MAXPATHLEN)
+                       return; /* Should be impossible... */
+               memcpy(partial_string_buf + partial_string_len, arg, arg_len + 1);
+               partial_string_len = 0;
+               arg = partial_string_buf;
+       }
        if (relative_paths) {
                if ((cp = strstr(arg, "/./")) != NULL)
                        arg = cp + 3;
diff --git a/io.c b/io.c
index a6e3ed30c14bb35f1bb7f0c5f8fb659ed322c8ea..7111878ac2590952feb9ae42275bdfcc27d49c93 100644 (file)
--- a/io.c
+++ b/io.c
@@ -376,6 +376,7 @@ static void forward_filesfrom_data(void)
                        free_xbuf(&ff_xb);
                        if (ff_reenable_multiplex >= 0)
                                io_start_multiplex_out(ff_reenable_multiplex);
+                       free_implied_include_partial_string();
                }
                return;
        }
@@ -435,6 +436,7 @@ static void forward_filesfrom_data(void)
                        ff_lastchar = '\0';
                else {
                        /* Handle a partial string specially, saving any incomplete chars. */
+                       implied_include_partial_string(sob, s);
                        flags &= ~ICB_INCLUDE_INCOMPLETE;
                        if (iconvbufs(ic_send, &ff_xb, &iobuf.out, flags) < 0) {
                                if (errno == E2BIG)
@@ -461,6 +463,7 @@ static void forward_filesfrom_data(void)
                                        f++;
                        }
                }
+               implied_include_partial_string(cur, t);
                ff_lastchar = f[-1];
                if ((len = t - ff_xb.buf) != 0) {
                        /* This will not circle back to perform_io() because we only get