Author: bodewig Date: Mon Dec 5 09:58:04 2011 New Revision: 1210386 URL: http://svn.apache.org/viewvc?rev=1210386&view=rev Log: Add read-support for big files using GNU tar extensions. write support will be added later. Based on patch by John Kodis. COMPRESS-16
Modified: commons/proper/compress/trunk/pom.xml commons/proper/compress/trunk/src/changes/changes.xml commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveEntry.java commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/tar/TarUtils.java Modified: commons/proper/compress/trunk/pom.xml URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/pom.xml?rev=1210386&r1=1210385&r2=1210386&view=diff ============================================================================== --- commons/proper/compress/trunk/pom.xml (original) +++ commons/proper/compress/trunk/pom.xml Mon Dec 5 09:58:04 2011 @@ -107,6 +107,9 @@ <name>Lasse Collin</name> <email>lasse.col...@tukaani.org</email> </contributor> + <contributor> + <name>John Kodis</name> + </contributor> </contributors> <scm> Modified: commons/proper/compress/trunk/src/changes/changes.xml URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/changes/changes.xml?rev=1210386&r1=1210385&r2=1210386&view=diff ============================================================================== --- commons/proper/compress/trunk/src/changes/changes.xml (original) +++ commons/proper/compress/trunk/src/changes/changes.xml Mon Dec 5 09:58:04 2011 @@ -57,6 +57,10 @@ The <action> type attribute can be add,u GZipCompressorInputStream now optionally supports reading of concatenated .gz files. </action> + <action issue="COMPRESS-16" type="update" date="2011-12-05"> + The tar package can now read archives that use GNU extensions + for files that are longer than 8 GByte. + </action> </release> <release version="1.3" date="2011-11-01" description="Release 1.3 - API compatible to 1.2 but requires Java5 at runtime"> Modified: commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveEntry.java URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveEntry.java?rev=1210386&r1=1210385&r2=1210386&view=diff ============================================================================== --- commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveEntry.java (original) +++ commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveEntry.java Mon Dec 5 09:58:04 2011 @@ -789,7 +789,7 @@ public class TarArchiveEntry implements offset += UIDLEN; groupId = (int) TarUtils.parseOctal(header, offset, GIDLEN); offset += GIDLEN; - size = TarUtils.parseOctal(header, offset, SIZELEN); + size = TarUtils.parseOctalOrBinary(header, offset, SIZELEN); offset += SIZELEN; modTime = TarUtils.parseOctal(header, offset, MODTIMELEN); offset += MODTIMELEN; Modified: commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/tar/TarUtils.java URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/tar/TarUtils.java?rev=1210386&r1=1210385&r2=1210386&view=diff ============================================================================== --- commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/tar/TarUtils.java (original) +++ commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/tar/TarUtils.java Mon Dec 5 09:58:04 2011 @@ -106,6 +106,41 @@ public class TarUtils { return result; } + /** + * Compute the value contained in a byte buffer. If the most + * significant bit of the first byte in the buffer is set, this + * bit is ignored and the rest of the buffer is interpreted as a + * binary number. Otherwise, the buffer is interpreted as an + * octal number as per the parseOctal function above. + * + * @param buffer The buffer from which to parse. + * @param offset The offset into the buffer from which to parse. + * @param length The maximum number of bytes to parse. + * @return The long value of the octal or binary string. + * @throws IllegalArgumentException if the trailing space/NUL is + * missing or an invalid byte is detected in an octal number, or + * if a binary number would exceed the size of a signed long + * 64-bit integer. + */ + public static long parseOctalOrBinary(final byte[] buffer, final int offset, + final int length) { + + if ((buffer[offset] & 0x80) == 0) { + return parseOctal(buffer, offset, length); + } + + long val = buffer[offset] & 0x7f; + for (int i = 1; i < length; i++) { + if (val >= (1L << (63 - 8))) { + throw new IllegalArgumentException( + "At offset " + offset + ", " + length + " byte " + + "binary number exceeds maximum signed long value"); + } + val = (val << 8) + (buffer[offset + i] & 0xff); + } + return val; + } + /** * Parse a boolean byte from a buffer. * Leading spaces and NUL are ignored.