Skip to content

Commit

Permalink
#359 Add PasswordCallback for encrypted Input Streams
Browse files Browse the repository at this point in the history
  • Loading branch information
bio007 authored Oct 13, 2021
1 parent 7a13961 commit 2ec68db
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 6 deletions.
33 changes: 28 additions & 5 deletions src/main/java/net/lingala/zip4j/io/inputstream/ZipInputStream.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@

package net.lingala.zip4j.io.inputstream;

import static net.lingala.zip4j.util.InternalZipConstants.MIN_BUFF_SIZE;
import static net.lingala.zip4j.util.Zip4jUtil.getCompressionMethod;

import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.headers.HeaderReader;
import net.lingala.zip4j.headers.HeaderSignature;
Expand All @@ -28,6 +31,7 @@
import net.lingala.zip4j.model.enums.CompressionMethod;
import net.lingala.zip4j.model.enums.EncryptionMethod;
import net.lingala.zip4j.util.InternalZipConstants;
import net.lingala.zip4j.util.PasswordCallback;

import java.io.IOException;
import java.io.InputStream;
Expand All @@ -36,15 +40,13 @@
import java.util.List;
import java.util.zip.CRC32;

import static net.lingala.zip4j.util.InternalZipConstants.MIN_BUFF_SIZE;
import static net.lingala.zip4j.util.Zip4jUtil.getCompressionMethod;

public class ZipInputStream extends InputStream {

private PushbackInputStream inputStream;
private DecompressedInputStream decompressedInputStream;
private HeaderReader headerReader = new HeaderReader();
private char[] password;
private PasswordCallback passwordCallback;
private LocalFileHeader localFileHeader;
private CRC32 crc32 = new CRC32();
private byte[] endOfEntryBuffer;
Expand All @@ -54,28 +56,45 @@ public class ZipInputStream extends InputStream {
private boolean entryEOFReached = false;

public ZipInputStream(InputStream inputStream) {
this(inputStream, null, (Charset) null);
this(inputStream, (char[]) null, (Charset) null);
}

public ZipInputStream(InputStream inputStream, Charset charset) {
this(inputStream, null, charset);
this(inputStream, (char[]) null, charset);
}

public ZipInputStream(InputStream inputStream, char[] password) {
this(inputStream, password, (Charset) null);
}

public ZipInputStream(InputStream inputStream, PasswordCallback passwordCallback) {
this(inputStream, passwordCallback, (Charset) null);
}

public ZipInputStream(InputStream inputStream, char[] password, Charset charset) {
this(inputStream, password, new Zip4jConfig(charset, InternalZipConstants.BUFF_SIZE));
}

public ZipInputStream(InputStream inputStream, PasswordCallback passwordCallback, Charset charset) {
this(inputStream, passwordCallback, new Zip4jConfig(charset, InternalZipConstants.BUFF_SIZE));
}

public ZipInputStream(InputStream inputStream, char[] password, Zip4jConfig zip4jConfig) {
this(inputStream, password, null, zip4jConfig);
}

public ZipInputStream(InputStream inputStream, PasswordCallback passwordCallback, Zip4jConfig zip4jConfig) {
this(inputStream, null, passwordCallback, zip4jConfig);
}

private ZipInputStream(InputStream inputStream, char[] password, PasswordCallback passwordCallback, Zip4jConfig zip4jConfig) {
if (zip4jConfig.getBufferSize() < InternalZipConstants.MIN_BUFF_SIZE) {
throw new IllegalArgumentException("Buffer size cannot be less than " + MIN_BUFF_SIZE + " bytes");
}

this.inputStream = new PushbackInputStream(inputStream, zip4jConfig.getBufferSize());
this.password = password;
this.passwordCallback = passwordCallback;
this.zip4jConfig = zip4jConfig;
}

Expand All @@ -96,6 +115,10 @@ public LocalFileHeader getNextEntry(FileHeader fileHeader, boolean readUntilEndO
return null;
}

if (localFileHeader.isEncrypted() && password == null && passwordCallback != null) {
setPassword(passwordCallback.getPassword());
}

verifyLocalFileHeader(localFileHeader);
crc32.reset();

Expand Down
7 changes: 7 additions & 0 deletions src/main/java/net/lingala/zip4j/util/PasswordCallback.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package net.lingala.zip4j.util;

@FunctionalInterface
public interface PasswordCallback {

char[] getPassword();
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public void testZipInputStreamConstructorThrowsExceptionWhenBufferSizeIsLessThan
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Buffer size cannot be less than " + MIN_BUFF_SIZE + " bytes");

new ZipInputStream(inputStream, null, zip4jConfig);
new ZipInputStream(inputStream, (char[]) null, zip4jConfig);
}

@Test
Expand Down

0 comments on commit 2ec68db

Please sign in to comment.