This is an automated email from the ASF dual-hosted git repository. peterlee pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/commons-compress.git
commit a9a03f63895cabfa903415da19a581443592ee88 Author: theobisproject <theobisproj...@gmail.com> AuthorDate: Sat Dec 26 12:46:58 2020 +0100 COMPRESS-540: Implement reading of padded last record --- .../apache/commons/compress/archivers/tar/TarFile.java | 15 +++++++++++++-- .../archivers/tar/TarArchiveInputStreamTest.java | 3 +++ .../commons/compress/archivers/tar/TarFileTest.java | 16 ++++++++++++++++ 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/apache/commons/compress/archivers/tar/TarFile.java b/src/main/java/org/apache/commons/compress/archivers/tar/TarFile.java index dc4ab20..664d3ee 100644 --- a/src/main/java/org/apache/commons/compress/archivers/tar/TarFile.java +++ b/src/main/java/org/apache/commons/compress/archivers/tar/TarFile.java @@ -548,8 +548,7 @@ public class TarFile implements Closeable { if (isAtEOF() && headerBuf != null) { // Consume rest tryToConsumeSecondEOFRecord(); - // TODO: This is present in the TarArchiveInputStream but I don't know if we need this in the random access implementation. All tests are passing ... - // consumeRemainderOfLastBlock(); + consumeRemainderOfLastBlock(); headerBuf = null; } return headerBuf; @@ -580,6 +579,18 @@ public class TarFile implements Closeable { } /** + * This method is invoked once the end of the archive is hit, it + * tries to consume the remaining bytes under the assumption that + * the tool creating this archive has padded the last block. + */ + private void consumeRemainderOfLastBlock() throws IOException { + final long bytesReadOfLastBlock = archive.position() % blockSize; + if (bytesReadOfLastBlock > 0) { + archive.position(archive.position() + blockSize - bytesReadOfLastBlock); + } + } + + /** * Read a record from the input stream and return the data. * * @return The record data or null if EOF has been hit. diff --git a/src/test/java/org/apache/commons/compress/archivers/tar/TarArchiveInputStreamTest.java b/src/test/java/org/apache/commons/compress/archivers/tar/TarArchiveInputStreamTest.java index e7907b8..b86c835 100644 --- a/src/test/java/org/apache/commons/compress/archivers/tar/TarArchiveInputStreamTest.java +++ b/src/test/java/org/apache/commons/compress/archivers/tar/TarArchiveInputStreamTest.java @@ -123,6 +123,9 @@ public class TarArchiveInputStreamTest extends AbstractTestCase { tis.close(); } + /** + * This test ensures the implementation is reading the padded last block if a tool has added one to an archive + */ @Test public void shouldConsumeArchiveCompletely() throws Exception { final InputStream is = TarArchiveInputStreamTest.class diff --git a/src/test/java/org/apache/commons/compress/archivers/tar/TarFileTest.java b/src/test/java/org/apache/commons/compress/archivers/tar/TarFileTest.java index 1360320..07c8a6b 100644 --- a/src/test/java/org/apache/commons/compress/archivers/tar/TarFileTest.java +++ b/src/test/java/org/apache/commons/compress/archivers/tar/TarFileTest.java @@ -23,6 +23,8 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.nio.channels.SeekableByteChannel; import java.nio.file.Files; import java.nio.file.Path; import java.util.Calendar; @@ -110,6 +112,20 @@ public class TarFileTest extends AbstractTestCase { } } + /** + * This test ensures the implementation is reading the padded last block if a tool has added one to an archive + */ + @Test + public void archiveWithTrailer() throws IOException { + try (final SeekableByteChannel channel = Files.newByteChannel(getPath("archive_with_trailer.tar")); + final TarFile tarfile = new TarFile(channel, TarConstants.DEFAULT_BLKSIZE, TarConstants.DEFAULT_RCDSIZE, null, false)) { + final String tarAppendix = "Hello, world!\n"; + final ByteBuffer buffer = ByteBuffer.allocate(tarAppendix.length()); + channel.read(buffer); + assertEquals(tarAppendix, new String(buffer.array())); + } + } + @Test public void readsArchiveCompletely_COMPRESS245() throws Exception { try {