COMPRESS-450 allow tar to search for the next good tar header
Project: http://git-wip-us.apache.org/repos/asf/commons-compress/repo Commit: http://git-wip-us.apache.org/repos/asf/commons-compress/commit/3a0ac2ca Tree: http://git-wip-us.apache.org/repos/asf/commons-compress/tree/3a0ac2ca Diff: http://git-wip-us.apache.org/repos/asf/commons-compress/diff/3a0ac2ca Branch: refs/heads/COMPRESS-450 Commit: 3a0ac2ca83436ebe59cbe91e241f6a245125f0b1 Parents: 27ff599 Author: Stefan Bodewig <bode...@apache.org> Authored: Tue May 1 12:52:48 2018 +0200 Committer: Stefan Bodewig <bode...@apache.org> Committed: Tue May 1 12:52:48 2018 +0200 ---------------------------------------------------------------------- .../archivers/tar/TarArchiveInputStream.java | 27 +++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/commons-compress/blob/3a0ac2ca/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveInputStream.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveInputStream.java b/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveInputStream.java index a5ade6e..d5d9ca0 100644 --- a/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveInputStream.java +++ b/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveInputStream.java @@ -80,6 +80,9 @@ public class TarArchiveInputStream extends ArchiveInputStream { // the global PAX header private Map<String, String> globalPaxHeaders = new HashMap<>(); + /** Whether the last attempt to read an ArchiveEntry failed */ + private boolean headerErrorOccurred = false; + /** * Constructor for TarInputStream. * @param is the input stream to use @@ -257,6 +260,10 @@ public class TarArchiveInputStream extends ArchiveInputStream { * * @return The next TarEntry in the archive, or null. * @throws IOException on error + * @throws InvalidTarHeaderException if the next block cannot be + * parsed as a tar header. In this case it may be possible to skip + * some corrupted blocks and process the next valid tar header by + * calling this method again. */ public TarArchiveEntry getNextTarEntry() throws IOException { if (isAtEOF()) { @@ -269,9 +276,27 @@ public class TarArchiveInputStream extends ArchiveInputStream { /* skip to the end of the last record */ skipRecordPadding(); + + /* Set currEntry to null, to make sure we don't skip again + if reading the next header fails */ + currEntry = null; + entrySize = 0; } - final byte[] headerBuf = getRecord(); + byte[] headerBuf = getRecord(); + + if (headerErrorOccurred) { + do { + try { + if (TarUtils.verifyCheckSum(headerBuf)) { + break; + } + } catch (IllegalArgumentException e) { //NOSONAR + // next record is not a valid tar header either + } + entryOffset += recordSize; + } while ((headerBuf = getRecord()) != null); + } if (headerBuf == null) { /* hit EOF */