]> git.ipfire.org Git - thirdparty/rsync.git/commitdiff
Skip an append if sender's file gets shorter.
authorWayne Davison <wayne@opencoder.net>
Mon, 21 Sep 2020 21:40:23 +0000 (14:40 -0700)
committerWayne Davison <wayne@opencoder.net>
Mon, 21 Sep 2020 21:57:45 +0000 (14:57 -0700)
Fixes bug #90.  Similar to a pull request by Tomas Korbar.

NEWS.md
rsync.1.md
sender.c

diff --git a/NEWS.md b/NEWS.md
index 87119e4c6218cfb20335550449cbc13ab4b19aa5..405e86d12e09a7eb4eb7d679d869e65c9ba42a60 100644 (file)
--- a/NEWS.md
+++ b/NEWS.md
    for files that are being skipped due to an identical modify time.  (This
    was a new output quirk in 3.2.3.)
 
+ - When doing an append transfer, the sending side's file must not get shorter
+   or it is skipped. Fixes a crash that could occur when the size changes to 0
+   in the middle of the send negotiations.
+
  - Avoid a weird failure if you run a local copy with a (useless) `--rsh`
    option that contains a `V`.
 
index ec971eccddbf74dd236702d6729d33cfa3726045..7bb4c5a1b4dc44abba3173bbb685ae6c8c60429f 100644 (file)
@@ -949,7 +949,9 @@ your home directory (remove the '=' for that).
     existing content in the file (it only verifies the content that it is
     appending).  Rsync skips any files that exist on the receiving side that
     are not shorter than the associated file on the sending side (which means
-    that new files are trasnferred).
+    that new files are trasnferred).  It also skips any files whose size on the
+    sending side gets shorter during the send negotiations (rsync warns about a
+    "diminished" file when this happens).
 
     This does not interfere with the updating of a file's non-content
     attributes (e.g.  permissions, ownership, etc.) when the file does not need
index 94761c2624f1ba62c65d316b5854a3c76945b828..9cfca134a7d519f29d2ed54641299f18d95d5240 100644 (file)
--- a/sender.c
+++ b/sender.c
@@ -362,6 +362,16 @@ void send_files(int f_in, int f_out)
                        exit_cleanup(RERR_FILEIO);
                }
 
+               if (append_mode > 0 && st.st_size < F_LENGTH(file)) {
+                       rprintf(FWARNING, "skipped diminished file: %s\n",
+                               full_fname(fname));
+                       free_sums(s);
+                       close(fd);
+                       if (protocol_version >= 30)
+                               send_msg_int(MSG_NO_SEND, ndx);
+                       continue;
+               }
+
                if (st.st_size) {
                        int32 read_size = MAX(s->blength * 3, MAX_MAP_SIZE);
                        mbuf = map_file(fd, st.st_size, read_size, s->blength);