Browse Source

propely handle GNU longlink entries, PR 55040, submitted by Christoph Gysin

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@1488951 13f79535-47bb-0310-9956-ffa450edef68
master
Stefan Bodewig 12 years ago
parent
commit
1a22123f5c
6 changed files with 71 additions and 21 deletions
  1. +1
    -0
      CONTRIBUTORS
  2. +3
    -0
      WHATSNEW
  3. +4
    -0
      contributors.xml
  4. +5
    -0
      src/main/org/apache/tools/tar/TarConstants.java
  5. +10
    -0
      src/main/org/apache/tools/tar/TarEntry.java
  6. +48
    -21
      src/main/org/apache/tools/tar/TarInputStream.java

+ 1
- 0
CONTRIBUTORS View File

@@ -50,6 +50,7 @@ Charles Hudak
Charlie Hubbard
Chris Povirk
Christian Knorr
Christoph Gysin
Christoph Wilhelms
Christophe Labouisse
Christopher A. Longo


+ 3
- 0
WHATSNEW View File

@@ -12,6 +12,9 @@ Fixed bugs:
be able to read archives created by DotNetZip and maybe other
archivers as well.

* TarInputStream should now properly read GNU longlink entries' names.
Bugzilla Report 55040.

Other changes:
--------------



+ 4
- 0
contributors.xml View File

@@ -221,6 +221,10 @@
<first>Christian</first>
<last>Knorr</last>
</name>
<name>
<first>Christoph</first>
<last>Gysin</last>
</name>
<name>
<first>Christoph</first>
<last>Wilhelms</last>


+ 5
- 0
src/main/org/apache/tools/tar/TarConstants.java View File

@@ -237,6 +237,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.
*/


+ 10
- 0
src/main/org/apache/tools/tar/TarEntry.java View File

@@ -652,6 +652,16 @@ public class TarEntry implements TarConstants {
return linkFlag == LF_GNUTYPE_SPARSE;
}

/**
* 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
*


+ 48
- 21
src/main/org/apache/tools/tar/TarInputStream.java View File

@@ -303,31 +303,25 @@ public class TarInputStream extends FilterInputStream {
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) {
if (currEntry.isGNULongLinkEntry()) {
byte[] longLinkData = getLongNameData();
if (longLinkData == null) {
// Bugzilla: 40334
// Malformed tar file - long entry name not followed by entry
// Malformed tar file - long link 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;
currEntry.setLinkName(encoding.decode(longLinkData));
}
if (currEntry.isGNULongNameEntry()) {
byte[] longNameData = getLongNameData();
if (longNameData == null) {
// Bugzilla: 40334
// Malformed tar file - long entry name not followed by
// entry
return null;
}
currEntry.setName(encoding.decode(longNameData));
}

@@ -347,6 +341,39 @@ public class TarInputStream extends FilterInputStream {
return currEntry;
}

/**
* 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


Loading…
Cancel
Save