sparker
sparker

Reputation: 1578

Exception happened when untarring the Tar file using Apache Commons compress

I am trying to untar the tar file to a map using Apache commons compress in Java. I am able to untar most of the tar files but few are failing with the below Exception. I am not sure what is causing the issue. is the tar file corrupted? I am able to untar the file using 7zip in windows but the same file failing when programatically untar it. I am using Appache commons-compress 1.18

java.io.IOException: Error detected parsing the header
at org.apache.commons.compress.archivers.tar.TarArchiveInputStream.getNextTarEntry(TarArchiveInputStream.java:285)
at org.apache.commons.compress.archivers.tar.TarArchiveInputStream.getNextEntry(TarArchiveInputStream.java:552)

Caused by: java.lang.IllegalArgumentException: At offset 124, 12 byte binary number exceeds maximum signed long value
at org.apache.commons.compress.archivers.tar.TarUtils.parseBinaryBigInteger(TarUtils.java:213)
at org.apache.commons.compress.archivers.tar.TarUtils.parseOctalOrBinary(TarUtils.java:177)
at org.apache.commons.compress.archivers.tar.TarArchiveEntry.parseTarHeader(TarArchiveEntry.java:1283)
at org.apache.commons.compress.archivers.tar.TarArchiveEntry.parseTarHeader(TarArchiveEntry.java:1266)
at org.apache.commons.compress.archivers.tar.TarArchiveEntry.<init>(TarArchiveEntry.java:404)
at org.apache.commons.compress.archivers.tar.TarArchiveInputStream.getNextTarEntry(TarArchiveInputStream.java:283)
... 25 more

below is my code

public static Map<String, byte[]> unTarToMap(byte[] b) throws IOException, ArchiveException {
        final Map<String, byte[]> untaredFiles = new HashMap<>();
        ByteArrayInputStream is = new ByteArrayInputStream(b);
        final TarArchiveInputStream debInputStream = (TarArchiveInputStream) new ArchiveStreamFactory().createArchiveInputStream("tar", is);
        TarArchiveEntry entry;
        while ((entry = (TarArchiveEntry) debInputStream.getNextEntry()) != null) {
            final ByteArrayOutputStream outputFileStream = new ByteArrayOutputStream();
            IOUtils.copy(debInputStream, outputFileStream);
            outputFileStream.close();
            untaredFiles.put(entry.getName(), outputFileStream.toByteArray());
        }
        debInputStream.close();
        return untaredFiles;
    }

Upvotes: 2

Views: 2354

Answers (1)

user4524982
user4524982

Reputation:

You might be hitting a limitation of Commons Compress. At offset 124 of its header a tar entry stores its size. Commons Compress tries to represent the size as a Java long which has got a maximum value which is pretty large (2^63-1) but in theory tar entries could be bigger.

Either you have got a tar archive with entries that big (7z should be able to tell you how big it thinks the entry is) or you are hitting a bug. There are lots of different dialects of tar and it is quite possible Commons Compress thinks your archive is using a specific dialect when it isn't. In that case it would be best to open a bug report with Apache Commons Compress at https://issues.apache.org/jira/projects/COMPRESS/ and - if possible - provide the archive causing the exception.

BTW the line numbers in your stack trace do not match Compress 1.18 so you are probably not using the version you think you are.

Upvotes: 1

Related Questions