summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2022-09-02 16:32:27 -0500
committerPaul Eggert <eggert@cs.ucla.edu>2022-09-02 16:33:47 -0500
commitf8e14746d2ca72804a4520c059d7bf65ca00c5ac (patch)
tree455dde125161a38e5f56d9ce7afe08133aa9c1dc
parent35d9845d5d410237e418113ec79d8f9e4b0b2bb8 (diff)
downloadtar-f8e14746d2ca72804a4520c059d7bf65ca00c5ac.tar.gz
Fix --delete bug with short reads
* gnulib.modules: Add idx. * src/common.h: Include idx.h. * src/delete.c (move_archive): Don’t botch short reads.
-rw-r--r--gnulib.modules1
-rw-r--r--src/common.h1
-rw-r--r--src/delete.c10
3 files changed, 10 insertions, 2 deletions
diff --git a/gnulib.modules b/gnulib.modules
index 63e8354a..dac77d61 100644
--- a/gnulib.modules
+++ b/gnulib.modules
@@ -54,6 +54,7 @@ gettime
gitlog-to-changelog
hash
human
+idx
inttostr
inttypes
lchown
diff --git a/src/common.h b/src/common.h
index 58c1b6c1..24166524 100644
--- a/src/common.h
+++ b/src/common.h
@@ -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>
diff --git a/src/delete.c b/src/delete.c
index 1d4d2681..3bee5c65 100644
--- a/src/delete.c
+++ b/src/delete.c
@@ -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]));