You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by pe...@apache.org on 2020/09/07 06:40:08 UTC
[commons-compress] branch master updated: COMPRESS-550 : add
writePreamble to ZipArchiveInputStream
This is an automated email from the ASF dual-hosted git repository.
peterlee pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-compress.git
The following commit(s) were added to refs/heads/master by this push:
new a40c53d COMPRESS-550 : add writePreamble to ZipArchiveInputStream
a40c53d is described below
commit a40c53d1494d71d09f57880f1a333445ddf4c535
Author: PeterAlfredLee <pe...@gmail.com>
AuthorDate: Tue Aug 18 15:22:39 2020 +0800
COMPRESS-550 : add writePreamble to ZipArchiveInputStream
Add writePreamble to ZipArchiveInputStream. This is used to create
self-extracting zips.
---
.../archivers/zip/ZipArchiveOutputStream.java | 29 ++++++++
.../compress/archivers/zip/ZipFileTest.java | 80 ++++++++++++++++++++++
2 files changed, 109 insertions(+)
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 e145e6d..3d63bf2 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
@@ -1005,6 +1005,35 @@ public class ZipArchiveOutputStream extends ArchiveOutputStream {
}
/**
+ * Write preamble data. For most of time, this is used to
+ * make self-extracting zips.
+ *
+ * @param preamble data to write
+ * @throws IOException if an entry already exists
+ * @since 1.21
+ */
+ public void writePreamble(final byte[] preamble) throws IOException {
+ writePreamble(preamble, 0, preamble.length);
+ }
+
+ /**
+ * Write preamble data. For most of time, this is used to
+ * make self-extracting zips.
+ *
+ * @param preamble data to write
+ * @param offset the start offset in the data
+ * @param length the number of bytes to write
+ * @throws IOException if an entry already exists
+ * @since 1.21
+ */
+ public void writePreamble(final byte[] preamble, final int offset, final int length) throws IOException {
+ if (entry != null) {
+ throw new IllegalStateException("Preamble must be written before creating an entry");
+ }
+ this.streamCompressor.writeCounted(preamble, offset, length);
+ }
+
+ /**
* Writes bytes to ZIP entry.
* @param b the byte array to write
* @param offset the start position to write from
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 c2b6485..1d43752 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
@@ -763,6 +763,86 @@ public class ZipFileTest {
outputStream.setLevel(Deflater.BEST_COMPRESSION + 1);
}
+ @Test(expected = IllegalStateException.class)
+ public void throwsExceptionWhenWritingPreamble() throws IOException {
+ final ZipArchiveOutputStream outputStream = new ZipArchiveOutputStream(new ByteArrayOutputStream());
+ outputStream.putArchiveEntry(new ZipArchiveEntry());
+ outputStream.writePreamble(new byte[0]);
+ }
+
+ @Test
+ public void testSelfExtractingZipUsingUnzipsfx() throws IOException, InterruptedException {
+ final File unzipsfx = new File("/usr/bin/unzipsfx");
+ if (!unzipsfx.exists()) {
+ return;
+ }
+
+ final File testZip = File.createTempFile("commons-compress-selfExtractZipTest", ".zip");
+ testZip.deleteOnExit();
+
+ final String testEntryName = "test_self_extract_zip/foo";
+ final File extractedFile = new File(testZip.getParentFile(), testEntryName);
+ extractedFile.deleteOnExit();
+
+ OutputStream outputStream = null;
+ InputStream inputStream = null;
+ final byte[] testData = new byte[]{1, 2, 3, 4};
+ byte[] buffer = new byte[512];
+ int bytesRead;
+ try (InputStream unzipsfxInputStream = new FileInputStream(unzipsfx)) {
+ outputStream = new FileOutputStream(testZip);
+ final ZipArchiveOutputStream zo = new ZipArchiveOutputStream(outputStream);
+
+ while ((bytesRead = unzipsfxInputStream.read(buffer)) > 0) {
+ zo.writePreamble(buffer, 0, bytesRead);
+ }
+
+ ZipArchiveEntry ze = new ZipArchiveEntry(testEntryName);
+ ze.setMethod(ZipEntry.STORED);
+ ze.setSize(4);
+ ze.setCrc(0xb63cfbcdl);
+ zo.putArchiveEntry(ze);
+ zo.write(testData);
+ zo.closeArchiveEntry();
+ zo.close();
+ outputStream.close();
+ outputStream = null;
+
+ final ProcessBuilder pbChmod = new ProcessBuilder("chmod", "+x", testZip.getPath());
+ pbChmod.redirectErrorStream(true);
+ final Process processChmod = pbChmod.start();
+ assertEquals(new String(IOUtils.toByteArray(processChmod.getInputStream())), 0, processChmod.waitFor());
+
+ final ProcessBuilder pb = new ProcessBuilder(testZip.getPath());
+ pb.redirectOutput(ProcessBuilder.Redirect.PIPE);
+ pb.directory(testZip.getParentFile());
+ pb.redirectErrorStream(true);
+ final Process process = pb.start();
+ assertEquals(new String(IOUtils.toByteArray(process.getInputStream())), 0, process.waitFor());
+
+ if (!extractedFile.exists()) {
+ // fail if extracted file does not exist
+ fail("Can not find the extracted file");
+ }
+
+ inputStream = new FileInputStream(extractedFile);
+ bytesRead = IOUtils.readFully(inputStream, buffer);
+ assertEquals(testData.length, bytesRead);
+ assertArrayEquals(testData, Arrays.copyOfRange(buffer, 0, bytesRead));
+ } finally {
+ if (outputStream != null) {
+ outputStream.close();
+ }
+ if (inputStream != null) {
+ inputStream.close();
+ }
+
+ testZip.delete();
+ extractedFile.delete();
+ extractedFile.getParentFile().delete();
+ }
+ }
+
private void multiByteReadConsistentlyReturnsMinusOneAtEof(final File file) throws Exception {
final byte[] buf = new byte[2];
try (ZipFile archive = new ZipFile(file)) {