diff --git a/src/buffer.c b/src/buffer.c
index b5fa210b..dcbfd028 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -983,18 +983,28 @@ short_read (size_t status)
void
flush_archive (void)
{
- size_t buffer_level = current_block->buffer - record_start->buffer;
- record_start_block += record_end - record_start;
- current_block = record_start;
- record_end = record_start + blocking_factor;
-
+ size_t buffer_level;
+
if (access_mode == ACCESS_READ && time_to_start_writing)
{
access_mode = ACCESS_WRITE;
time_to_start_writing = false;
backspace_output ();
+ if (record_end - record_start < blocking_factor)
+ {
+ memset (record_end, 0,
+ (blocking_factor - (record_end - record_start))
+ * BLOCKSIZE);
+ record_end = record_start + blocking_factor;
+ return;
+ }
}
+ buffer_level = current_block->buffer - record_start->buffer;
+ record_start_block += record_end - record_start;
+ current_block = record_start;
+ record_end = record_start + blocking_factor;
+
switch (access_mode)
{
case ACCESS_READ:
@@ -1034,7 +1044,7 @@ backspace_output (void)
/* Seek back to the beginning of this record and start writing there. */
- position -= record_size;
+ position -= record_end->buffer - record_start->buffer;
if (position < 0)
position = 0;
if (rmtlseek (archive, position, SEEK_SET) != position)
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 0772fab7..ee7a1d34 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -60,6 +60,7 @@ TESTSUITE_AT = \
append02.at\
append03.at\
append04.at\
+ append05.at\
backup01.at\
chtype.at\
comprec.at\
diff --git a/tests/append.at b/tests/append.at
index 88502db3..6fa587e3 100644
--- a/tests/append.at
+++ b/tests/append.at
@@ -27,7 +27,7 @@ AT_TAR_CHECK([touch file1
tar cf archive file1
tar rf archive file2
tar tf archive],
- [0],
+ [0],
[file1
file2
])
diff --git a/tests/append05.at b/tests/append05.at
new file mode 100644
index 00000000..865831a9
--- /dev/null
+++ b/tests/append05.at
@@ -0,0 +1,96 @@
+# Process this file with autom4te to create testsuite. -*- Autotest -*-
+#
+# Test suite for GNU tar.
+# Copyright 2016 Free Software Foundation, Inc.
+#
+# This file is part of GNU tar.
+#
+# GNU tar is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# GNU tar is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# Adding files to an archive with a blocking factor different from the one
+# used when creating it would produce a malformed archive.
+#
+# Last-Affected-Version: 1.28.90 (da7845c6563e7337bf3e8364046a7989091f190e)
+# Reported-by: Initial report by Renate Pyhel . Explained
+# in detail by Tim Kientzle. This test case is based on his posting.
+# References: ,
+# <50202013-27F2-4EFF-98C8-2DD112C5B956@kientzle.com>,
+# http://lists.gnu.org/archive/html/bug-tar/2016-03/msg00002.html,
+# http://lists.gnu.org/archive/html/bug-tar/2016-03/msg00004.html
+
+AT_SETUP([append after changed blocking])
+AT_KEYWORDS([append append05 blocking])
+
+AT_TAR_CHECK([
+for f in a b c d e f g h i
+do
+ echo $f > $f
+done
+
+decho 'creating archive'
+tar -cf archive -b1 a b c
+
+tar tf archive
+
+decho 'adding d e f'
+tar -vrf archive -b3 d e f
+echo ==
+tar tf archive
+
+decho 'adding g h i'
+tar -vrf archive -b5 g h i
+
+decho 'resulting archive'
+tar tf archive
+],
+[0],
+[creating archive
+a
+b
+c
+adding d e f
+d
+e
+f
+==
+a
+b
+c
+d
+e
+f
+adding g h i
+g
+h
+i
+resulting archive
+a
+b
+c
+d
+e
+f
+g
+h
+i
+],
+[creating archive
+adding d e f
+adding g h i
+resulting archive
+])
+
+AT_CLEANUP
+
+
diff --git a/tests/testsuite.at b/tests/testsuite.at
index 954d48cd..2e4a0679 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -243,6 +243,7 @@ m4_include([append01.at])
m4_include([append02.at])
m4_include([append03.at])
m4_include([append04.at])
+m4_include([append05.at])
AT_BANNER([Transforms])
m4_include([xform-h.at])