You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by bo...@apache.org on 2013/06/03 11:20:31 UTC
svn commit: r1488935 - in /commons/proper/compress/trunk/src: changes/
main/java/org/apache/commons/compress/archivers/tar/
test/java/org/apache/commons/compress/archivers/ test/resources/longsymlink/
Author: bodewig
Date: Mon Jun 3 09:20:30 2013
New Revision: 1488935
URL: http://svn.apache.org/r1488935
Log:
COMPRESS-229 properly parse GNU_LONGLNK entries, patch by Christoph Gysin
Added:
commons/proper/compress/trunk/src/test/resources/longsymlink/
commons/proper/compress/trunk/src/test/resources/longsymlink/files.txt (with props)
commons/proper/compress/trunk/src/test/resources/longsymlink/gnu.tar (with props)
Modified:
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/TarArchiveInputStream.java
commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/tar/TarConstants.java
commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/LongPathTest.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=1488935&r1=1488934&r2=1488935&view=diff
==============================================================================
--- commons/proper/compress/trunk/src/changes/changes.xml (original)
+++ commons/proper/compress/trunk/src/changes/changes.xml Mon Jun 3 09:20:30 2013
@@ -54,6 +54,12 @@ The <action> type attribute can be add,u
to be able to read archives created by DotNetZip and maybe
other archivers as well.
</action>
+ <action type="fix" date="2013-06-03" issue="COMPRESS-229"
+ due-to="Christoph Gysin">
+ TAR will now properly read the names of symbolic links with
+ long names that use the GNU variant to specify the long file
+ name.
+ </action>
</release>
<release version="1.5" date="2013-03-14"
description="Release 1.5">
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=1488935&r1=1488934&r2=1488935&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 Jun 3 09:20:30 2013
@@ -676,6 +676,16 @@ public class TarArchiveEntry implements
}
/**
+ * Indicate if this entry is a GNU long linkname block
+ *
+ * @return true if this is a long name extension provided by GNU tar
+ */
+ public boolean isGNULongLinkEntry() {
+ return linkFlag == LF_GNUTYPE_LONGLINK
+ && name.equals(GNU_LONGLINK);
+ }
+
+ /**
* Indicate if this entry is a GNU long name block
*
* @return true if this is a long name extension provided by GNU tar
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=1488935&r1=1488934&r2=1488935&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 Mon Jun 3 09:20:30 2013
@@ -248,31 +248,13 @@ public class TarArchiveInputStream exten
entryOffset = 0;
entrySize = currEntry.getSize();
- if (currEntry.isGNULongNameEntry()) {
- // read in the name
- ByteArrayOutputStream longName = new ByteArrayOutputStream();
- int length = 0;
- while ((length = read(SMALL_BUF)) >= 0) {
- longName.write(SMALL_BUF, 0, length);
- }
- getNextEntry();
- if (currEntry == null) {
- // Bugzilla: 40334
- // Malformed tar file - long entry name not followed by entry
- return null;
- }
- byte[] longNameData = longName.toByteArray();
- // remove trailing null terminator(s)
- length = longNameData.length;
- while (length > 0 && longNameData[length - 1] == 0) {
- --length;
- }
- if (length != longNameData.length) {
- byte[] l = new byte[length];
- System.arraycopy(longNameData, 0, l, 0, length);
- longNameData = l;
- }
+ if (currEntry.isGNULongLinkEntry()) {
+ byte[] longLinkData = getLongNameData();
+ currEntry.setLinkName(encoding.decode(longLinkData));
+ }
+ if (currEntry.isGNULongNameEntry()) {
+ byte[] longNameData = getLongNameData();
currEntry.setName(encoding.decode(longNameData));
}
@@ -293,6 +275,39 @@ public class TarArchiveInputStream exten
}
/**
+ * Get the next entry in this tar archive as longname data.
+ *
+ * @return The next entry in the archive as longname data, or null.
+ * @throws IOException on error
+ */
+ protected byte[] getLongNameData() throws IOException {
+ // read in the name
+ ByteArrayOutputStream longName = new ByteArrayOutputStream();
+ int length = 0;
+ while ((length = read(SMALL_BUF)) >= 0) {
+ longName.write(SMALL_BUF, 0, length);
+ }
+ getNextEntry();
+ if (currEntry == null) {
+ // Bugzilla: 40334
+ // Malformed tar file - long entry name not followed by entry
+ return null;
+ }
+ byte[] longNameData = longName.toByteArray();
+ // remove trailing null terminator(s)
+ length = longNameData.length;
+ while (length > 0 && longNameData[length - 1] == 0) {
+ --length;
+ }
+ if (length != longNameData.length) {
+ byte[] l = new byte[length];
+ System.arraycopy(longNameData, 0, l, 0, length);
+ longNameData = l;
+ }
+ return longNameData;
+ }
+
+ /**
* Get the next record in this tar archive. This will skip
* over any remaining data in the current entry, if there
* is one, and place the input stream at the header of the
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=1488935&r1=1488934&r2=1488935&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 Mon Jun 3 09:20:30 2013
@@ -233,6 +233,11 @@ public interface TarConstants {
byte LF_CONTIG = (byte) '7';
/**
+ * Identifies the *next* file on the tape as having a long linkname.
+ */
+ byte LF_GNUTYPE_LONGLINK = (byte) 'K';
+
+ /**
* Identifies the *next* file on the tape as having a long name.
*/
byte LF_GNUTYPE_LONGNAME = (byte) 'L';
Modified: commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/LongPathTest.java
URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/LongPathTest.java?rev=1488935&r1=1488934&r2=1488935&view=diff
==============================================================================
--- commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/LongPathTest.java (original)
+++ commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/LongPathTest.java Mon Jun 3 09:20:30 2013
@@ -25,6 +25,8 @@ import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Map;
+import java.util.HashMap;
import junit.framework.AssertionFailedError;
import junit.framework.Test;
@@ -33,6 +35,7 @@ import junit.framework.TestSuite;
import org.apache.commons.compress.AbstractTestCase;
import org.apache.commons.compress.archivers.ar.ArArchiveInputStream;
import org.apache.commons.compress.archivers.cpio.CpioArchiveInputStream;
+import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
@@ -44,26 +47,37 @@ import org.apache.commons.compress.archi
*/
public class LongPathTest extends AbstractTestCase {
+ private String name;
private File file;
- private static final ArrayList<String> fileList = new ArrayList<String>();
+ private static final Map<String, ArrayList<String>> fileLists = new HashMap<String, ArrayList<String>>();
public LongPathTest(String name) {
super(name);
}
- private LongPathTest(String name, File file){
- super(name);
+ private LongPathTest(String name, String function, File file) {
+ super(function);
+ this.name = name;
this.file = file;
}
public static TestSuite suite() throws IOException{
TestSuite suite = new TestSuite("LongPathTests");
- File arcdir = getFile("longpath");
+ suite.addTest(createSuite("LongPathTest", "longpath"));
+ suite.addTest(createSuite("LongSymlinkTest", "longsymlink"));
+ return suite;
+ }
+
+ public static TestSuite createSuite(String name, String dirname) throws IOException {
+ TestSuite suite = new TestSuite(name);
+ File arcdir = getFile(dirname);
assertTrue(arcdir.exists());
File listing= new File(arcdir,"files.txt");
assertTrue("File listing is readable",listing.canRead());
BufferedReader br = new BufferedReader(new FileReader(listing));
+
+ ArrayList<String> fileList = new ArrayList<String>();
String line;
while ((line=br.readLine())!=null){
if (line.startsWith("#")){
@@ -71,6 +85,7 @@ public class LongPathTest extends Abstra
}
fileList.add(line);
}
+ fileLists.put(name, fileList);
br.close();
File[]files=arcdir.listFiles();
for (final File file : files) {
@@ -79,14 +94,25 @@ public class LongPathTest extends Abstra
}
// Appears to be the only way to give the test a variable name
TestSuite namedSuite = new TestSuite(file.getName());
- Test test = new LongPathTest("testArchive", file);
+ Test test = new LongPathTest(name, "testArchive", file);
namedSuite.addTest(test);
suite.addTest(namedSuite);
}
return suite;
}
+ protected String getExpectedString(ArchiveEntry entry) {
+ if (entry instanceof TarArchiveEntry) {
+ TarArchiveEntry tarEntry = (TarArchiveEntry) entry;
+ if (tarEntry.isSymbolicLink()) {
+ return tarEntry.getName() + " -> " + tarEntry.getLinkName();
+ }
+ }
+ return entry.getName();
+ }
+
public void testArchive() throws Exception {
+ ArrayList<String> fileList = fileLists.get(name);
@SuppressWarnings("unchecked") // fileList is of correct type
ArrayList<String> expected = (ArrayList<String>) fileList.clone();
String name = file.getName();
Added: commons/proper/compress/trunk/src/test/resources/longsymlink/files.txt
URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/test/resources/longsymlink/files.txt?rev=1488935&view=auto
==============================================================================
--- commons/proper/compress/trunk/src/test/resources/longsymlink/files.txt (added)
+++ commons/proper/compress/trunk/src/test/resources/longsymlink/files.txt Mon Jun 3 09:20:30 2013
@@ -0,0 +1 @@
+0xxxxxxxxx10xxxxxxxx20xxxxxxxx30xxxxxxxx40xxxxxxxx50xxxxxxxx60xxxxxxxx70xxxxxxxx80xxxxxxxx90xxxxxxxx100xxxxxxx110xxxxxxx120xxxxxxx130xxxxxxx -> 0yyyyyyyyy10yyyyyyyy20yyyyyyyy30yyyyyyyy40yyyyyyyy50yyyyyyyy60yyyyyyyy70yyyyyyyy80yyyyyyyy90yyyyyyyy100yyyyyyy110yyyyyyy120yyyyyyy130yyyyyyy
Propchange: commons/proper/compress/trunk/src/test/resources/longsymlink/files.txt
------------------------------------------------------------------------------
svn:eol-style = native
Added: commons/proper/compress/trunk/src/test/resources/longsymlink/gnu.tar
URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/test/resources/longsymlink/gnu.tar?rev=1488935&view=auto
==============================================================================
Binary file - no diff available.
Propchange: commons/proper/compress/trunk/src/test/resources/longsymlink/gnu.tar
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream