Author: bodewig
Date: Sat Jul 23 04:57:17 2011
New Revision: 1149798
URL: http://svn.apache.org/viewvc?rev=1149798&view=rev
Log:
detect sparse entries in tar and allow users to skip them. Submitted by
Patrick Dreyer. COMPRESS-145
Added:
commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveSparseEntry.java
(with props)
Modified:
commons/proper/compress/trunk/src/changes/changes.xml
commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/tar/TarConstants.java
commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/tar/TarUtils.java
Modified: commons/proper/compress/trunk/src/changes/changes.xml
URL:
http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/changes/changes.xml?rev=1149798&r1=1149797&r2=1149798&view=diff
==============================================================================
--- commons/proper/compress/trunk/src/changes/changes.xml (original)
+++ commons/proper/compress/trunk/src/changes/changes.xml Sat Jul 23 04:57:17
2011
@@ -45,7 +45,12 @@ The <action> type attribute can be add,u
</properties>
<body>
<release version="1.2" date="as in SVN" description="Release 1.2">
- <action issue="COMPRESS-123" type="add" date="2011-07.23">
+ <action issue="COMPRESS-145" type="fix" date="2011-07-23"
+ due-tue="Patrick Dreyer">
+ TarArchiveInputStream now detects sparse entries and properly
+ reports it cannot extract their contents.
+ </action>
+ <action issue="COMPRESS-123" type="add" date="2011-07-23">
ZipArchiveEntry has a new method getRawName that provides the
original bytes that made up the name. This may allow user
code to detect the encoding.
Added:
commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveSparseEntry.java
URL:
http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveSparseEntry.java?rev=1149798&view=auto
==============================================================================
---
commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveSparseEntry.java
(added)
+++
commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveSparseEntry.java
Sat Jul 23 04:57:17 2011
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.commons.compress.archivers.tar;
+
+import java.io.IOException;
+
+/**
+ * This class represents a sparse entry in a Tar archive.
+ *
+ * <p>
+ * The C structure for a sparse entry is:
+ * <pre>
+ * struct posix_header {
+ * struct sparse sp[21]; // TarConstants.SPARSELEN_GNU_SPARSE - offset 0
+ * char isextended; // TarConstants.ISEXTENDEDLEN_GNU_SPARSE - offset 504
+ * };
+ * </pre>
+ * Whereas, "struct sparse" is:
+ * <pre>
+ * struct sparse {
+ * char offset[12]; // offset 0
+ * char numbytes[12]; // offset 12
+ * };
+ * </pre>
+ */
+
+public class TarArchiveSparseEntry implements TarConstants {
+ /** If an extension sparse header follows. */
+ private boolean isExtended;
+
+ /**
+ * Construct an entry from an archive's header bytes. File is set
+ * to null.
+ *
+ * @param headerBuf The header bytes from a tar archive entry.
+ * @throws IOException on unknown format
+ */
+ public TarArchiveSparseEntry(byte[] headerBuf) throws IOException {
+ int offset = 0;
+ offset += SPARSELEN_GNU_SPARSE;
+ isExtended = TarUtils.parseBoolean(headerBuf, offset);
+ }
+
+ public boolean isExtended() {
+ return isExtended;
+ }
+}
Propchange:
commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveSparseEntry.java
------------------------------------------------------------------------------
svn:eol-style = native
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=1149798&r1=1149797&r2=1149798&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
Sat Jul 23 04:57:17 2011
@@ -21,11 +21,23 @@ package org.apache.commons.compress.arch
/**
* This interface contains all the definitions used in the package.
*
+ * For tar formats (FORMAT_OLDGNU, FORMAT_POSIX, etc.) see GNU tar
+ * <I>tar.h</I> type <I>enum archive_format</I>
*/
// CheckStyle:InterfaceIsTypeCheck OFF (bc)
public interface TarConstants {
/**
+ * GNU format as per before tar 1.12.
+ */
+ int FORMAT_OLDGNU = 2;
+
+ /**
+ * Pure Posix format.
+ */
+ int FORMAT_POSIX = 3;
+
+ /**
* The length of the name field in a header buffer.
*/
int NAMELEN = 100;
@@ -102,6 +114,66 @@ public interface TarConstants {
int PREFIXLEN = 155;
/**
+ * The length of the access time field in an old GNU header buffer.
+ *
+ */
+ int ATIMELEN_GNU = 12;
+
+ /**
+ * The length of the created time field in an old GNU header buffer.
+ *
+ */
+ int CTIMELEN_GNU = 12;
+
+ /**
+ * The length of the multivolume start offset field in an old GNU header
buffer.
+ *
+ */
+ int OFFSETLEN_GNU = 12;
+
+ /**
+ * The length of the long names field in an old GNU header buffer.
+ *
+ */
+ int LONGNAMESLEN_GNU = 4;
+
+ /**
+ * The length of the padding field in an old GNU header buffer.
+ *
+ */
+ int PAD2LEN_GNU = 1;
+
+ /**
+ * The sum of the length of all sparse headers in an old GNU header
buffer.
+ *
+ */
+ int SPARSELEN_GNU = 96;
+
+ /**
+ * The length of the is extension field in an old GNU header buffer.
+ *
+ */
+ int ISEXTENDEDLEN_GNU = 1;
+
+ /**
+ * The length of the real size field in an old GNU header buffer.
+ *
+ */
+ int REALSIZELEN_GNU = 12;
+
+ /**
+ * The sum of the length of all sparse headers in a sparse header buffer.
+ *
+ */
+ int SPARSELEN_GNU_SPARSE = 504;
+
+ /**
+ * The length of the is extension field in a sparse header buffer.
+ *
+ */
+ int ISEXTENDEDLEN_GNU_SPARSE = 1;
+
+ /**
* 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.
*/
@@ -152,6 +224,12 @@ public interface TarConstants {
*/
byte LF_GNUTYPE_LONGNAME = (byte) 'L';
+ /**
+ * Sparse file type.
+ * @since Apache Commons Compress 1.1.1
+ */
+ byte LF_GNUTYPE_SPARSE = (byte) 'S';
+
// See
"http://www.opengroup.org/onlinepubs/009695399/utilities/pax.html#tag_04_100_13_02"
/**
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=1149798&r1=1149797&r2=1149798&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
Sat Jul 23 04:57:17 2011
@@ -106,6 +106,21 @@ public class TarUtils {
return result;
}
+ /**
+ * Parse a boolean byte from a buffer.
+ * Leading spaces and NUL are ignored.
+ * The buffer may contain trailing spaces or NULs.
+ *
+ * @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 - must be at least 1
byte.
+ * @return The boolean value of the bytes.
+ * @throws IllegalArgumentException if an invalid byte is detected.
+ */
+ public static boolean parseBoolean(final byte[] buffer, final int offset) {
+ return (buffer[offset] == 1);
+ }
+
// Helper method to generate the exception message
private static String exceptionMessage(byte[] buffer, final int offset,
final int length, int current, final byte currentByte) {