Author: sebb Date: Thu Apr 2 23:34:48 2009 New Revision: 761475 URL: http://svn.apache.org/viewvc?rev=761475&view=rev Log: Split magic into magic and version Improve match() method so it works for Posix and GNU
Modified: 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/TarArchiveInputStream.java commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/tar/TarConstants.java 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=761475&r1=761474&r2=761475&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 Thu Apr 2 23:34:48 2009 @@ -54,24 +54,25 @@ * The C structure for a Tar Entry's header is: * <pre> * struct header { - * char name[100]; // TarConstants.NAMELEN - * char mode[8]; // TarConstants.MODELEN - * char uid[8]; // TarConstants.UIDLEN - * char gid[8]; // TarConstants.GIDLEN - * char size[12]; // TarConstants.SIZELEN - * char mtime[12]; // TarConstants.MODTIMELEN - * char chksum[8]; // TarConstants.CHKSUMLEN - * char linkflag[1]; - * char linkname[100]; // TarConstants.NAMELEN + * char name[100]; // TarConstants.NAMELEN - offset 0 + * char mode[8]; // TarConstants.MODELEN - offset 100 + * char uid[8]; // TarConstants.UIDLEN - offset 108 + * char gid[8]; // TarConstants.GIDLEN - offset 116 + * char size[12]; // TarConstants.SIZELEN - offset 124 + * char mtime[12]; // TarConstants.MODTIMELEN - offset 136 + * char chksum[8]; // TarConstants.CHKSUMLEN - offset 148 + * char linkflag[1]; // - offset 156 + * char linkname[100]; // TarConstants.NAMELEN - offset 157 * The following fields are only present in new-style POSIX tar archives: - * char magic[8]; // TarConstants.MAGICLEN - * TODO: Posix/GNU split this into magic[6] and char version[2]; - * char uname[32]; // TarConstants.UNAMELEN - * char gname[32]; // TarConstants.GNAMELEN - * char devmajor[8]; // TarConstants.DEVLEN - * char devminor[8]; // TarConstants.DEVLEN - * char prefix[155]; // Used if "name" field is not long enough to hold the path - * char pad[12]; // NULs + * char magic[6]; // TarConstants.MAGICLEN - offset 257 + * char version[2]; // TarConstants.VERSIONLEN - offset 263 + * char uname[32]; // TarConstants.UNAMELEN - offset 265 + * char gname[32]; // TarConstants.GNAMELEN - offset 297 + * char devmajor[8]; // TarConstants.DEVLEN - offset 329 + * char devminor[8]; // TarConstants.DEVLEN - offset 337 + * char prefix[155]; // TarConstants.PREFIXLEN - offset 345 + * // Used if "name" field is not long enough to hold the path + * char pad[12]; // NULs - offset 500 * } header; * All unused bytes are set to null. * New-style GNU tar files are slightly different from the above. @@ -107,6 +108,8 @@ /** The entry's magic tag. */ private String magic; + /** The version of the format */ + private String version; /** The entry's user name. */ private String userName; @@ -140,6 +143,7 @@ */ private TarArchiveEntry () { this.magic = MAGIC_POSIX; + this.version = VERSION_POSIX; this.name = ""; this.linkName = ""; @@ -577,6 +581,7 @@ outbuf[offset++] = linkFlag; offset = TarUtils.formatNameBytes(linkName, outbuf, offset, NAMELEN); offset = TarUtils.formatNameBytes(magic, outbuf, offset, MAGICLEN); + offset = TarUtils.formatNameBytes(version, outbuf, offset, VERSIONLEN); offset = TarUtils.formatNameBytes(userName, outbuf, offset, UNAMELEN); offset = TarUtils.formatNameBytes(groupName, outbuf, offset, GNAMELEN); offset = TarUtils.formatOctalBytes(devMajor, outbuf, offset, DEVLEN); @@ -617,6 +622,8 @@ offset += NAMELEN; magic = TarUtils.parseName(header, offset, MAGICLEN); offset += MAGICLEN; + version = TarUtils.parseName(header, offset, VERSIONLEN); + offset += VERSIONLEN; userName = TarUtils.parseName(header, offset, UNAMELEN); offset += UNAMELEN; groupName = TarUtils.parseName(header, offset, GNAMELEN); Modified: commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveInputStream.java URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveInputStream.java?rev=761475&r1=761474&r2=761475&view=diff ============================================================================== --- commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveInputStream.java (original) +++ commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveInputStream.java Thu Apr 2 23:34:48 2009 @@ -28,6 +28,7 @@ import java.io.OutputStream; import org.apache.commons.compress.archivers.ArchiveEntry; import org.apache.commons.compress.archivers.ArchiveInputStream; +import org.apache.commons.compress.utils.ArchiveUtils; /** * The TarInputStream reads a UNIX tar archive as an InputStream. @@ -380,39 +381,32 @@ // ArchiveInputStream public static boolean matches(byte[] signature, int length) { - // 6574 7473 2e31 6d78 == "test1.xml" - // TODO replace with a proper test if possible - see COMPRESS-65 - - if (length < 8) { + if (length < TarConstants.VERSION_OFFSET+TarConstants.VERSIONLEN) { return false; } - if (signature[0] != 0x74) { - return false; + if (ArchiveUtils.matchAsciiBuffer(TarConstants.MAGIC_POSIX, + signature, TarConstants.MAGIC_OFFSET, TarConstants.MAGICLEN) + && + ArchiveUtils.matchAsciiBuffer(TarConstants.VERSION_POSIX, + signature, TarConstants.VERSION_OFFSET, TarConstants.VERSIONLEN) + ){ + return true; + } + if (ArchiveUtils.matchAsciiBuffer(TarConstants.MAGIC_GNU, + signature, TarConstants.MAGIC_OFFSET, TarConstants.MAGICLEN) + && + ( + ArchiveUtils.matchAsciiBuffer(TarConstants.VERSION_GNU_SPACE, + signature, TarConstants.VERSION_OFFSET, TarConstants.VERSIONLEN) + || + ArchiveUtils.matchAsciiBuffer(TarConstants.VERSION_GNU_ZERO, + signature, TarConstants.VERSION_OFFSET, TarConstants.VERSIONLEN) + ) + ){ + return true; } - if (signature[1] != 0x65) { - return false; - } - if (signature[2] != 0x73) { - return false; - } - if (signature[3] != 0x74) { - return false; - } - if (signature[4] != 0x31) { - return false; - } - if (signature[5] != 0x2e) { - return false; - } - if (signature[6] != 0x78) { - return false; - } - if (signature[7] != 0x6d) { - return false; - } - - return true; + return false; } } Modified: commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/tar/TarConstants.java URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/tar/TarConstants.java?rev=761475&r1=761474&r2=761475&view=diff ============================================================================== --- commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/tar/TarConstants.java (original) +++ commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/tar/TarConstants.java Thu Apr 2 23:34:48 2009 @@ -60,10 +60,19 @@ */ long MAXSIZE = 077777777777L; + /** Offset of start of magic field within header record */ + int MAGIC_OFFSET = 257; /** * The length of the magic field in a header buffer. */ - int MAGICLEN = 8; // TODO split this into MAGICLEN=6 and VERSIONLEN=2 + int MAGICLEN = 6; + + /** Offset of start of magic field within header record */ + int VERSION_OFFSET = 263; + /** + * Previously this was regarded as part of "magic" field, but it is separate. + */ + int VERSIONLEN = 2; /** * The length of the modification time field in a header buffer. @@ -86,6 +95,12 @@ int DEVLEN = 8; /** + * Length of the prefix field. + * + */ + int PREFIXLEN = 155; + + /** * LF_ constants represent the "link flag" of an entry, or more commonly, * the "entry type". This is the "old way" of indicating a normal file. */ @@ -134,12 +149,16 @@ /** * The magic tag representing a POSIX tar archive. */ - String MAGIC_POSIX = "ustar"; // TODO this should be NUL-terminated + String MAGIC_POSIX = "ustar\0"; + String VERSION_POSIX = "00"; /** * The magic tag representing a GNU tar archive. */ - String MAGIC_GNU = "ustar "; // TODO this should have single space terminator + String MAGIC_GNU = "ustar "; + // Appear to be two possible GNU versions + String VERSION_GNU_SPACE = " \0"; + String VERSION_GNU_ZERO = "0\0"; /** * The name of the GNU tar entry which contains a long name.