[GitHub] [ant] helfper opened a new pull request #145: Override ZipOutputStream.write(int)

classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

[GitHub] [ant] helfper opened a new pull request #145: Override ZipOutputStream.write(int)

GitBox

helfper opened a new pull request #145:
URL: https://github.com/apache/ant/pull/145


   `java.util.zip.ZipOutputStream` extends from `java.util.zip.DeflaterOutputStream` which overrides `void write(int b)` to redirect its calls to `void write(byte[] b, int off, int len)`.
   
   `org.apache.tools.zip.ZipOutputStream` doesn't extend the same class and currently doesn't override `void write(int b)`. This means that calls to this method end up in `FilterOutputStream.write(int b)`, which in turn passes them through to the underlying `OutputStream`. This bypasses all the logic in `ZipOutputStream.write(byte[] b, int offset, int len)` (deflation and whatnot) which produces corrupted ZIP files.
   
   One example where the method `void write(int b)` is ultimately invoked is by calling `java.util.jar.Manifest.write(zipOutputStream)`.
   
   This PR fixes this by overriding the method `void write(int b)` in `org.apache.tools.zip.ZipOutputStream` in the same way as `java.util.zip.DeflaterOutputStream` does.


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
[hidden email]



---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

[GitHub] [ant] bodewig commented on a change in pull request #145: Override ZipOutputStream.write(int)

GitBox

bodewig commented on a change in pull request #145:
URL: https://github.com/apache/ant/pull/145#discussion_r593741630



##########
File path: src/main/org/apache/tools/zip/ZipOutputStream.java
##########
@@ -901,6 +901,20 @@ public boolean canWriteEntryData(ZipEntry ae) {
         return ZipUtil.canHandleEntryData(ae);
     }
 
+    /**
+     * Writes a byte to ZIP entry.
+     *
+     * @param b the byte to write
+     * @throws IOException on error
+     * @since Ant 1.10.10
+     */
+    @Override
+    public void write(int b) throws IOException {
+        byte[] buf = new byte[1];

Review comment:
       We could allocate a one-byte array and reuse that for all calls. Of course then we'd need to think about thread safety issues. So maybe that's not wort the trouble given that so far nobody seems to have used that method anyway :-)




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
[hidden email]



---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

[GitHub] [ant] bodewig commented on a change in pull request #145: Override ZipOutputStream.write(int)

GitBox
In reply to this post by GitBox

bodewig commented on a change in pull request #145:
URL: https://github.com/apache/ant/pull/145#discussion_r593741717



##########
File path: src/tests/junit/org/apache/tools/zip/ZipOutputStreamTest.java
##########
@@ -70,4 +76,17 @@ public void testAdjustToLong() {
                      ZipUtil.adjustToLong(2 * Integer.MAX_VALUE));
     }
 
+    @Test
+    public void testWriteAndReadManifest() throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ZipOutputStream zos = new ZipOutputStream(baos);
+        zos.putNextEntry(new ZipEntry(JarFile.MANIFEST_NAME));
+        new Manifest().write(zos);
+        zos.close();
+        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+        ZipInputStream zis = new ZipInputStream(bais);
+        zis.getNextEntry();
+        zis.closeEntry();
+        zis.close();
+    }

Review comment:
       please use try-with-resources for all streams even though we are only writing to memory.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
[hidden email]



---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

[GitHub] [ant] bodewig commented on pull request #145: Override ZipOutputStream.write(int)

GitBox
In reply to this post by GitBox

bodewig commented on pull request #145:
URL: https://github.com/apache/ant/pull/145#issuecomment-798236533


   Many thanks - interesting this has been there for more then a decade. Most likely this is because Ant is supposed to be the only consumer of the class and doesn't use the single byte write method itself. For general use I'd recommend to use `ZipArchiveOutputStream` of Apache Commons Compress which is a grandchild of Ant's zip package.
   
   @helfper please add yourself to the contributors.xml and CONTRIBUTORS files in Ant's top level.


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
[hidden email]



---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

[GitHub] [ant] helfper commented on a change in pull request #145: Override ZipOutputStream.write(int)

GitBox
In reply to this post by GitBox

helfper commented on a change in pull request #145:
URL: https://github.com/apache/ant/pull/145#discussion_r593746382



##########
File path: src/main/org/apache/tools/zip/ZipOutputStream.java
##########
@@ -901,6 +901,20 @@ public boolean canWriteEntryData(ZipEntry ae) {
         return ZipUtil.canHandleEntryData(ae);
     }
 
+    /**
+     * Writes a byte to ZIP entry.
+     *
+     * @param b the byte to write
+     * @throws IOException on error
+     * @since Ant 1.10.10
+     */
+    @Override
+    public void write(int b) throws IOException {
+        byte[] buf = new byte[1];

Review comment:
       Agreed, I thought about that but was wondering why `DeflaterOutputStream` didn't do it. I did it now as this class is not thread-safe anyway, and this allocation on every write may keep the GC unnecessarily busy. I checked Apache Commons Compress since you mentioned it and it's also it's done there: https://github.com/apache/commons-compress/blob/master/src/main/java/org/apache/commons/compress/archivers/ArchiveOutputStream.java#L52




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
[hidden email]



---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

[GitHub] [ant] helfper commented on a change in pull request #145: Override ZipOutputStream.write(int)

GitBox
In reply to this post by GitBox

helfper commented on a change in pull request #145:
URL: https://github.com/apache/ant/pull/145#discussion_r593746382



##########
File path: src/main/org/apache/tools/zip/ZipOutputStream.java
##########
@@ -901,6 +901,20 @@ public boolean canWriteEntryData(ZipEntry ae) {
         return ZipUtil.canHandleEntryData(ae);
     }
 
+    /**
+     * Writes a byte to ZIP entry.
+     *
+     * @param b the byte to write
+     * @throws IOException on error
+     * @since Ant 1.10.10
+     */
+    @Override
+    public void write(int b) throws IOException {
+        byte[] buf = new byte[1];

Review comment:
       Agreed, I thought about that but was wondering why `DeflaterOutputStream` didn't do it. I did it now as this class is not thread-safe anyway, and this allocation on every write may keep the GC unnecessarily busy. I checked Apache Commons Compress since you mentioned it and it's also how it's done there: https://github.com/apache/commons-compress/blob/master/src/main/java/org/apache/commons/compress/archivers/ArchiveOutputStream.java#L52




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
[hidden email]



---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

[GitHub] [ant] helfper commented on a change in pull request #145: Override ZipOutputStream.write(int)

GitBox
In reply to this post by GitBox

helfper commented on a change in pull request #145:
URL: https://github.com/apache/ant/pull/145#discussion_r593746440



##########
File path: src/tests/junit/org/apache/tools/zip/ZipOutputStreamTest.java
##########
@@ -70,4 +76,17 @@ public void testAdjustToLong() {
                      ZipUtil.adjustToLong(2 * Integer.MAX_VALUE));
     }
 
+    @Test
+    public void testWriteAndReadManifest() throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ZipOutputStream zos = new ZipOutputStream(baos);
+        zos.putNextEntry(new ZipEntry(JarFile.MANIFEST_NAME));
+        new Manifest().write(zos);
+        zos.close();
+        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+        ZipInputStream zis = new ZipInputStream(bais);
+        zis.getNextEntry();
+        zis.closeEntry();
+        zis.close();
+    }

Review comment:
       Done now.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
[hidden email]



---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

[GitHub] [ant] helfper commented on pull request #145: Override ZipOutputStream.write(int)

GitBox
In reply to this post by GitBox

helfper commented on pull request #145:
URL: https://github.com/apache/ant/pull/145#issuecomment-798310215


   @bodewig I've updated the contributors files now.
   
   I've found the issue in https://github.com/johnrengelman/shadow which uses Ant's `ZipOutputStream`. Out of curiosity, why doesn't Ant use Commons Compress's `ZipArchiveOutputStream`?


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
[hidden email]



---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

[GitHub] [ant] bodewig commented on pull request #145: Override ZipOutputStream.write(int)

GitBox
In reply to this post by GitBox

bodewig commented on pull request #145:
URL: https://github.com/apache/ant/pull/145#issuecomment-798341657


   Ant predates Commons Compress by several years.
   
   Actually Ant's core doesn't have any dependencies at all, this has always been the case. Initially the XML parser had to be provided before JAXP became part of the standard class library. This is an important goal of Ant. We can bootstrap Ant with just a JDK and nothing else.


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
[hidden email]



---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

[GitHub] [ant] bodewig merged pull request #145: Override ZipOutputStream.write(int)

GitBox
In reply to this post by GitBox

bodewig merged pull request #145:
URL: https://github.com/apache/ant/pull/145


   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
[hidden email]



---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]