diff --git a/src/main/org/apache/tools/tar/TarOutputStream.java b/src/main/org/apache/tools/tar/TarOutputStream.java index 350801ea1..0f4eae316 100644 --- a/src/main/org/apache/tools/tar/TarOutputStream.java +++ b/src/main/org/apache/tools/tar/TarOutputStream.java @@ -28,6 +28,7 @@ import java.io.FilterOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.StringWriter; +import java.nio.ByteBuffer; import java.util.HashMap; import java.util.Map; import org.apache.tools.zip.ZipEncoding; @@ -272,9 +273,10 @@ public class TarOutputStream extends FilterOutputStream { } Map paxHeaders = new HashMap(); final String entryName = entry.getName(); - final byte[] nameBytes = encoding.encode(entryName).array(); + final ByteBuffer encodedName = encoding.encode(entryName); + final int nameLen = encodedName.limit() - encodedName.position(); boolean paxHeaderContainsPath = false; - if (nameBytes.length >= TarConstants.NAMELEN) { + if (nameLen >= TarConstants.NAMELEN) { if (longFileMode == LONGFILE_POSIX) { paxHeaders.put("path", entryName); @@ -285,9 +287,9 @@ public class TarOutputStream extends FilterOutputStream { TarEntry longLinkEntry = new TarEntry(TarConstants.GNU_LONGLINK, TarConstants.LF_GNUTYPE_LONGNAME); - longLinkEntry.setSize(nameBytes.length + 1); // +1 for NUL + longLinkEntry.setSize(nameLen + 1); // +1 for NUL putNextEntry(longLinkEntry); - write(nameBytes); + write(encodedName.array(), encodedName.arrayOffset(), nameLen); write(0); // NUL terminator closeEntry(); } else if (longFileMode != LONGFILE_TRUNCATE) { @@ -483,6 +485,11 @@ public class TarOutputStream extends FilterOutputStream { void writePaxHeaders(String entryName, Map headers) throws IOException { String name = "./PaxHeaders.X/" + stripTo7Bits(entryName); + while (name.endsWith("/")) { + // TarEntry's constructor would think this is a directory + // and not allow any data to be written + name = name.substring(0, name.length() - 1); + } if (name.length() >= TarConstants.NAMELEN) { name = name.substring(0, TarConstants.NAMELEN - 1); } diff --git a/src/main/org/apache/tools/tar/TarUtils.java b/src/main/org/apache/tools/tar/TarUtils.java index c71a43d03..e88f6b40d 100644 --- a/src/main/org/apache/tools/tar/TarUtils.java +++ b/src/main/org/apache/tools/tar/TarUtils.java @@ -350,7 +350,7 @@ public class TarUtils { while (b.limit() > length && len > 0) { b = encoding.encode(name.substring(0, --len)); } - final int limit = b.limit(); + final int limit = b.limit() - b.position(); System.arraycopy(b.array(), b.arrayOffset(), buf, offset, limit); // Pad any remaining output bytes with NUL diff --git a/src/main/org/apache/tools/zip/ZipOutputStream.java b/src/main/org/apache/tools/zip/ZipOutputStream.java index 31cb75fab..92a3d82b0 100644 --- a/src/main/org/apache/tools/zip/ZipOutputStream.java +++ b/src/main/org/apache/tools/zip/ZipOutputStream.java @@ -986,7 +986,8 @@ public class ZipOutputStream extends FilterOutputStream { written += SHORT; // file name - writeOut(name.array(), name.arrayOffset(), name.limit()); + writeOut(name.array(), name.arrayOffset(), + name.limit() - name.position()); written += name.limit(); // extra field @@ -1009,7 +1010,8 @@ public class ZipOutputStream extends FilterOutputStream { ze.addExtraField(new UnicodePathExtraField(ze.getName(), name.array(), name.arrayOffset(), - name.limit())); + name.limit() + - name.position())); } String comm = ze.getComment(); @@ -1023,7 +1025,8 @@ public class ZipOutputStream extends FilterOutputStream { ze.addExtraField(new UnicodeCommentExtraField(comm, commentB.array(), commentB.arrayOffset(), - commentB.limit()) + commentB.limit() + - commentB.position()) ); } } @@ -1159,7 +1162,8 @@ public class ZipOutputStream extends FilterOutputStream { written += WORD; // file name - writeOut(name.array(), name.arrayOffset(), name.limit()); + writeOut(name.array(), name.arrayOffset(), + name.limit() - name.position()); written += name.limit(); // extra field @@ -1167,7 +1171,8 @@ public class ZipOutputStream extends FilterOutputStream { written += extra.length; // file comment - writeOut(commentB.array(), commentB.arrayOffset(), commentB.limit()); + writeOut(commentB.array(), commentB.arrayOffset(), + commentB.limit() - commentB.position()); written += commentB.limit(); } @@ -1233,7 +1238,8 @@ public class ZipOutputStream extends FilterOutputStream { // ZIP file comment ByteBuffer data = this.zipEncoding.encode(comment); writeOut(ZipShort.getBytes(data.limit())); - writeOut(data.array(), data.arrayOffset(), data.limit()); + writeOut(data.array(), data.arrayOffset(), + data.limit() - data.position()); } /**