]> git.ipfire.org Git - thirdparty/tar.git/commitdiff
Fix --delete bug with short reads
authorPaul Eggert <eggert@cs.ucla.edu>
Fri, 2 Sep 2022 21:32:27 +0000 (16:32 -0500)
committerPaul Eggert <eggert@cs.ucla.edu>
Fri, 2 Sep 2022 21:33:47 +0000 (16:33 -0500)
* gnulib.modules: Add idx.
* src/common.h: Include idx.h.
* src/delete.c (move_archive): Don’t botch short reads.

gnulib.modules
src/common.h
src/delete.c

index 63e8354adde51fe87352caca16e567554828fad2..dac77d61d7bf765e18a25f9a9da0837659bdbc97 100644 (file)
@@ -54,6 +54,7 @@ gettime
 gitlog-to-changelog
 hash
 human
+idx
 inttostr
 inttypes
 lchown
index 58c1b6c1e53efe9523dab48ecf317d0dc78ec305..241665249b39e0ff3ffc46f49604047bfdbb75b7 100644 (file)
@@ -53,6 +53,7 @@
 #include <backupfile.h>
 #include <exclude.h>
 #include <full-write.h>
+#include <idx.h>
 #include <modechange.h>
 #include <quote.h>
 #include <safe-read.h>
index 1d4d2681fbf61c04e3be653660e7a83bf29a339f..3bee5c65f1a679d0ddd2f5e89235ffbdbb24076c 100644 (file)
@@ -55,9 +55,15 @@ move_archive (off_t count)
   off_t position0 = rmtlseek (archive, 0, SEEK_CUR), position = 0;
   if (0 <= position0)
     {
-      off_t increment;
+      /* Pretend the starting position is at the first record
+        boundary after POSITION0.  This is useful at EOF after
+        a short read.  */
+      idx_t short_size = position0 % record_size;
+      idx_t start_offset = short_size ? record_size - short_size : 0;
+      off_t increment, move_start;
       if (INT_MULTIPLY_WRAPV (record_size, count, &increment)
-         || INT_ADD_WRAPV (position0, increment, &position)
+         || INT_ADD_WRAPV (position0, start_offset, &move_start)
+         || INT_ADD_WRAPV (move_start, increment, &position)
          || position < 0)
        {
          ERROR ((0, EOVERFLOW, "lseek: %s", archive_name_array[0]));