deal with existing PaddingExtraFields when calculating the alignment
Project: http://git-wip-us.apache.org/repos/asf/commons-compress/repo Commit: http://git-wip-us.apache.org/repos/asf/commons-compress/commit/702f27a8 Tree: http://git-wip-us.apache.org/repos/asf/commons-compress/tree/702f27a8 Diff: http://git-wip-us.apache.org/repos/asf/commons-compress/diff/702f27a8 Branch: refs/heads/master Commit: 702f27a8779fa77a2ea0a1b6cc6e1e4d678d4fbb Parents: e3e137d Author: Stefan Bodewig <bode...@apache.org> Authored: Wed May 10 09:55:52 2017 +0200 Committer: Stefan Bodewig <bode...@apache.org> Committed: Thu May 11 20:04:34 2017 +0200 ---------------------------------------------------------------------- .../archivers/zip/PaddingExtraField.java | 2 +- .../archivers/zip/ZipArchiveOutputStream.java | 9 +++++++-- .../compress/archivers/zip/ZipFileTest.java | 19 ++++++++++++++++++- 3 files changed, 26 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/commons-compress/blob/702f27a8/src/main/java/org/apache/commons/compress/archivers/zip/PaddingExtraField.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/compress/archivers/zip/PaddingExtraField.java b/src/main/java/org/apache/commons/compress/archivers/zip/PaddingExtraField.java index 28df2e6..590cc93 100644 --- a/src/main/java/org/apache/commons/compress/archivers/zip/PaddingExtraField.java +++ b/src/main/java/org/apache/commons/compress/archivers/zip/PaddingExtraField.java @@ -35,7 +35,7 @@ public class PaddingExtraField implements ZipExtraField { * Extra field id used for padding (there is no special value documented, * therefore USHORT_MAX seems to be good choice). */ - private static final ZipShort ID = new ZipShort(0xffff); + public static final ZipShort ID = new ZipShort(0xffff); private int len = 0; http://git-wip-us.apache.org/repos/asf/commons-compress/blob/702f27a8/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java b/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java index 7161301..359f92b 100644 --- a/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java +++ b/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java @@ -1044,13 +1044,18 @@ public class ZipArchiveOutputStream extends ArchiveOutputStream { final boolean phased, long archiveOffset) throws IOException { byte[] extra = ze.getLocalFileDataExtra(); final int nameLen = name.limit() - name.position(); - int len= LFH_FILENAME_OFFSET + nameLen + extra.length; + int len = LFH_FILENAME_OFFSET + nameLen + extra.length; int alignment = ze.getAlignment(); if (alignment > 1 && ((archiveOffset + len) & (alignment - 1)) != 0) { int padding = (int) ((-archiveOffset - len - EXTRAFIELD_HEADER_SIZE) & (alignment - 1)); + ZipExtraField pex = (PaddingExtraField) ze.getExtraField(PaddingExtraField.ID); + if (pex != null) { + padding += pex.getLocalFileDataLength().getValue() + EXTRAFIELD_HEADER_SIZE; + } + // will overwrite an existing PaddingExtraField ze.addExtraField(new PaddingExtraField(padding)); extra = ze.getLocalFileDataExtra(); - len += EXTRAFIELD_HEADER_SIZE + padding; + len = LFH_FILENAME_OFFSET + nameLen + extra.length; } final byte[] buf = new byte[len]; http://git-wip-us.apache.org/repos/asf/commons-compress/blob/702f27a8/src/test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java b/src/test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java index 0c94368..98d6dcc 100644 --- a/src/test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java +++ b/src/test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java @@ -482,6 +482,14 @@ public class ZipFileTest { zipOutput.write("Hello Stored\n".getBytes(Charset.forName("UTF-8"))); zipOutput.closeArchiveEntry(); + ZipArchiveEntry storedEntry2 = new ZipArchiveEntry("stored2.txt"); + storedEntry2.setMethod(ZipEntry.STORED); + storedEntry2.setAlignment(1024); + storedEntry2.addExtraField(new PaddingExtraField(123)); + zipOutput.putArchiveEntry(storedEntry2); + zipOutput.write("Hello pre-aligned Stored\n".getBytes(Charset.forName("UTF-8"))); + zipOutput.closeArchiveEntry(); + } try (ZipFile zf = new ZipFile(new SeekableInMemoryByteChannel( @@ -498,11 +506,20 @@ public class ZipFileTest { ZipArchiveEntry storedEntry = zf.getEntry("stored.txt"); assertNotEquals(-1L, storedEntry.getCompressedSize()); assertNotEquals(-1L, storedEntry.getSize()); - assertEquals(0L, inflatedEntry.getDataOffset()%1024); + assertEquals(0L, storedEntry.getDataOffset()%1024); try (InputStream stream = zf.getInputStream(storedEntry)) { Assert.assertEquals("Hello Stored\n", new String(IOUtils.toByteArray(stream), Charset.forName("UTF-8"))); } + + ZipArchiveEntry storedEntry2 = zf.getEntry("stored2.txt"); + assertNotEquals(-1L, storedEntry2.getCompressedSize()); + assertNotEquals(-1L, storedEntry2.getSize()); + assertEquals(0L, storedEntry2.getDataOffset()%1024); + try (InputStream stream = zf.getInputStream(storedEntry2)) { + Assert.assertEquals("Hello pre-aligned Stored\n", + new String(IOUtils.toByteArray(stream), Charset.forName("UTF-8"))); + } } }