You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by pe...@apache.org on 2021/01/09 03:20:42 UTC

[commons-compress] 09/13: COMPRESS-540: Implement reading of padded last record

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 <th...@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 {