[Git][java-team/zip4j][upstream] New upstream version 2.1.3
Andrius Merkys
gitlab at salsa.debian.org
Thu Sep 12 08:55:18 BST 2019
Andrius Merkys pushed to branch upstream at Debian Java Maintainers / zip4j
Commits:
40f52713 by Andrius Merkys at 2019-09-12T07:03:46Z
New upstream version 2.1.3
- - - - -
22 changed files:
- README.md
- pom.xml
- src/main/java/net/lingala/zip4j/ZipFile.java
- src/main/java/net/lingala/zip4j/crypto/PBKDF2/PBKDF2Engine.java
- src/main/java/net/lingala/zip4j/io/inputstream/ZipInputStream.java
- src/main/java/net/lingala/zip4j/io/outputstream/CipherOutputStream.java
- src/main/java/net/lingala/zip4j/io/outputstream/ZipEntryOutputStream.java
- src/main/java/net/lingala/zip4j/model/ZipParameters.java
- src/main/java/net/lingala/zip4j/tasks/AbstractAddFileToZipTask.java
- src/main/java/net/lingala/zip4j/tasks/AbstractExtractFileTask.java
- src/main/java/net/lingala/zip4j/util/UnzipUtil.java
- src/test/java/net/lingala/zip4j/AddFilesToZipIT.java
- src/test/java/net/lingala/zip4j/CreateZipFileIT.java
- src/test/java/net/lingala/zip4j/ExtractZipFileIT.java
- src/test/java/net/lingala/zip4j/MiscZipFileIT.java
- src/test/java/net/lingala/zip4j/ZipFileTest.java
- src/test/java/net/lingala/zip4j/headers/HeaderUtilTest.java
- src/test/java/net/lingala/zip4j/io/inputstream/ZipInputStreamIT.java
- src/test/java/net/lingala/zip4j/testutils/TestUtils.java
- src/test/java/net/lingala/zip4j/testutils/ZipFileVerifier.java
- src/test/java/net/lingala/zip4j/util/CrcUtilIT.java
- src/test/java/net/lingala/zip4j/util/FileUtilsTest.java
Changes:
=====================================
README.md
=====================================
@@ -61,7 +61,7 @@ once again, and makes me support Zip4j as much as I can.
<dependency>
<groupId>net.lingala.zip4j</groupId>
<artifactId>zip4j</artifactId>
- <version>2.1.2</version>
+ <version>2.1.3</version>
</dependency>
~~~~
@@ -78,7 +78,7 @@ new ZipFile("filename.zip").addFile("filename.ext");
Or
~~~~
-new ZipFile("filename.zip").addFile("filename.ext");
+new ZipFile("filename.zip").addFile(new File("filename.ext"));
~~~~
### Creating a zip file with multiple files / Adding multiple files to an existing zip
@@ -253,7 +253,7 @@ new ZipFile("filename.zip").removeFile("root-folder/folder1/fileNameInZipToRemov
~~~~
If you want to be sure that the file you want to remove exists in zip file or if you don't want to deal with file names
-as string when dealing `removeFile` api, you can use the other overloaded method which takes in a `FileHeader:
+as string when dealing `removeFile` api, you can use the other overloaded method which takes in a `FileHeader`:
~~~~
ZipFile zipFile = new ZipFile("someZip.zip");
@@ -329,30 +329,32 @@ new ZipFile("valid_zip_file.zip").isValidZipFile();
### Adding entries with ZipOutputStream
~~~~
-import net.lingala.zip4j.AbstractIT;
-import net.lingala.zip4j.exception.ZipException;
+import net.lingala.zip4j.io.outputstream.ZipOutputStream;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.model.enums.AesKeyStrength;
import net.lingala.zip4j.model.enums.CompressionMethod;
import net.lingala.zip4j.model.enums.EncryptionMethod;
-import org.junit.Test;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.util.List;
+
+public class ZipOutputStreamExample {
-public void zipOutputStreamExample(CompressionMethod compressionMethod, boolean encrypt,
- EncryptionMethod encryptionMethod, AesKeyStrength aesKeyStrength)
- throws IOException, ZipException {
+ public void zipOutputStreamExample(File outputZipFile, List<File> filesToAdd, char[] password,
+ CompressionMethod compressionMethod, boolean encrypt,
+ EncryptionMethod encryptionMethod, AesKeyStrength aesKeyStrength)
+ throws IOException {
ZipParameters zipParameters = buildZipParameters(compressionMethod, encrypt, encryptionMethod, aesKeyStrength);
byte[] buff = new byte[4096];
int readLen;
- try(ZipOutputStream zos = initializeZipOutputStream(encrypt) {
- for (File fileToAdd : FILES_TO_ADD) {
+ try(ZipOutputStream zos = initializeZipOutputStream(outputZipFile, encrypt, password)) {
+ for (File fileToAdd : filesToAdd) {
// Entry size has to be set if you want to add entries of STORE compression method (no compression)
// This is not required for deflate compression
@@ -371,19 +373,21 @@ public void zipOutputStreamExample(CompressionMethod compressionMethod, boolean
zos.closeEntry();
}
}
-}
+ }
-private ZipOutputStream initializeZipOutputStream(boolean encrypt) throws IOException {
- FileOutputStream fos = new FileOutputStream(generatedZipFile);
+ private ZipOutputStream initializeZipOutputStream(File outputZipFile, boolean encrypt, char[] password)
+ throws IOException {
+
+ FileOutputStream fos = new FileOutputStream(outputZipFile);
if (encrypt) {
- return new ZipOutputStream(fos, PASSWORD);
+ return new ZipOutputStream(fos, password);
}
return new ZipOutputStream(fos);
-}
+ }
-private ZipParameters buildZipParameters(CompressionMethod compressionMethod, boolean encrypt,
+ private ZipParameters buildZipParameters(CompressionMethod compressionMethod, boolean encrypt,
EncryptionMethod encryptionMethod, AesKeyStrength aesKeyStrength) {
ZipParameters zipParameters = new ZipParameters();
zipParameters.setCompressionMethod(compressionMethod);
@@ -391,16 +395,15 @@ private ZipParameters buildZipParameters(CompressionMethod compressionMethod, bo
zipParameters.setAesKeyStrength(aesKeyStrength);
zipParameters.setEncryptFiles(encrypt);
return zipParameters;
+ }
}
~~~~
### Extract files with ZipInputStream
~~~~
-import net.lingala.zip4j.ZipFile;
-import net.lingala.zip4j.exception.ZipException;
+import net.lingala.zip4j.io.inputstream.ZipInputStream;
import net.lingala.zip4j.model.LocalFileHeader;
-import net.lingala.zip4j.model.ZipParameters;
import java.io.File;
import java.io.FileInputStream;
@@ -408,25 +411,28 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
-public void extractWithInputStream(File zipFile, char[] password) throws IOException, ZipException {
+public class ZipInputStreamExample {
+
+ public void extractWithZipInputStream(File zipFile, char[] password) throws IOException {
LocalFileHeader localFileHeader;
int readLen;
byte[] readBuffer = new byte[4096];
- try (FileInputStream fileInputStream = new FileInputStream(zipFile)) {
- try (ZipInputStream zipInputStream = new ZipInputStream(fileInputStream, password)) {
- while ((localFileHeader = zipInputStream.getNextEntry()) != null) {
- File extractedFile = new File(localFileHeader.getFileName());
- try (OutputStream outputStream = new FileOutputStream(extractedFile)) {
- while ((readLen = zipInputStream.read(readBuffer)) != -1) {
- outputStream.write(readBuffer, 0, readLen);
- }
+ try (FileInputStream fileInputStream = new FileInputStream(zipFile);
+ ZipInputStream zipInputStream = new ZipInputStream(fileInputStream, password)) {
+ while ((localFileHeader = zipInputStream.getNextEntry()) != null) {
+ File extractedFile = new File(localFileHeader.getFileName());
+ try (OutputStream outputStream = new FileOutputStream(extractedFile)) {
+ while ((readLen = zipInputStream.read(readBuffer)) != -1) {
+ outputStream.write(readBuffer, 0, readLen);
}
}
}
}
+ }
}
+
~~~~
## Working with Progress Monitor
=====================================
pom.xml
=====================================
@@ -6,7 +6,7 @@
<groupId>net.lingala.zip4j</groupId>
<artifactId>zip4j</artifactId>
- <version>2.1.3-SNAPSHOT</version>
+ <version>2.1.4-SNAPSHOT</version>
<name>Zip4j</name>
<description>Zip4j - A Java library for zip files and streams</description>
=====================================
src/main/java/net/lingala/zip4j/ZipFile.java
=====================================
@@ -535,8 +535,7 @@ public class ZipFile {
}
/**
- * Returns the list of file headers in the zip file. Throws an exception if the
- * zip file does not exist
+ * Returns the list of file headers in the zip file. Returns an empty list if the zip file does not exist.
*
* @return list of file headers
* @throws ZipException
@@ -760,7 +759,7 @@ public class ZipFile {
* @return ZipInputStream
* @throws ZipException
*/
- public ZipInputStream getInputStream(FileHeader fileHeader) throws ZipException {
+ public ZipInputStream getInputStream(FileHeader fileHeader) throws IOException {
if (fileHeader == null) {
throw new ZipException("FileHeader is null, cannot get InputStream");
}
@@ -809,6 +808,14 @@ public class ZipFile {
return FileUtils.getSplitZipFiles(zipModel);
}
+ /**
+ * Sets a password to be used for the zip file. Will override if a password supplied via ZipFile constructor
+ * @param password - char array of the password to be used
+ */
+ public void setPassword(char[] password) {
+ this.password = password;
+ }
+
/**
* Reads the zip header information for this zip file. If the zip file
* does not exist, then this method throws an exception.<br><br>
=====================================
src/main/java/net/lingala/zip4j/crypto/PBKDF2/PBKDF2Engine.java
=====================================
@@ -42,7 +42,6 @@ public class PBKDF2Engine {
}
public byte[] deriveKey(char[] inputPassword, int dkLen) {
- byte[] r;
byte p[];
if (inputPassword == null) {
throw new NullPointerException();
=====================================
src/main/java/net/lingala/zip4j/io/inputstream/ZipInputStream.java
=====================================
@@ -49,6 +49,7 @@ public class ZipInputStream extends InputStream {
private LocalFileHeader localFileHeader;
private CRC32 crc32 = new CRC32();
private boolean extraDataRecordReadForThisEntry = false;
+ private byte[] endOfEntryBuffer;
public ZipInputStream(InputStream inputStream) {
this(inputStream, null);
@@ -64,6 +65,10 @@ public class ZipInputStream extends InputStream {
}
public LocalFileHeader getNextEntry(FileHeader fileHeader) throws IOException {
+ if (localFileHeader != null) {
+ readUntilEndOfEntry();
+ }
+
localFileHeader = headerReader.readLocalFileHeader(inputStream);
if (localFileHeader == null) {
@@ -300,6 +305,13 @@ public class ZipInputStream extends InputStream {
}
}
+ private void readUntilEndOfEntry() throws IOException {
+ if (endOfEntryBuffer == null) {
+ endOfEntryBuffer = new byte[512];
+ }
+ while (read(endOfEntryBuffer) != -1);
+ }
+
private boolean isEncryptionMethodZipStandard(LocalFileHeader localFileHeader) {
return localFileHeader.isEncrypted() && EncryptionMethod.ZIP_STANDARD.equals(localFileHeader.getEncryptionMethod());
}
=====================================
src/main/java/net/lingala/zip4j/io/outputstream/CipherOutputStream.java
=====================================
@@ -67,10 +67,6 @@ abstract class CipherOutputStream<T extends Encrypter> extends OutputStream {
return zipEntryOutputStream.getNumberOfBytesWrittenForThisEntry();
}
- public void decrementBytesWrittenForThisEntry(int value) {
- zipEntryOutputStream.decrementBytesWrittenForThisEntry(value);
- }
-
protected T getEncrypter() {
return encrypter;
}
=====================================
src/main/java/net/lingala/zip4j/io/outputstream/ZipEntryOutputStream.java
=====================================
@@ -42,14 +42,6 @@ class ZipEntryOutputStream extends OutputStream {
return numberOfBytesWrittenForThisEntry;
}
- public void decrementBytesWrittenForThisEntry(int value) {
- if (value <= 0) return;
-
- if (value <= this.numberOfBytesWrittenForThisEntry) {
- this.numberOfBytesWrittenForThisEntry -= value;
- }
- }
-
@Override
public void close() throws IOException {
// Do nothing
=====================================
src/main/java/net/lingala/zip4j/model/ZipParameters.java
=====================================
@@ -39,6 +39,7 @@ public class ZipParameters {
private long lastModifiedFileTime = System.currentTimeMillis();
private long entrySize = -1;
private boolean writeExtendedLocalFileHeader = true;
+ private boolean overrideExistingFilesInZip = true;
public ZipParameters() {
}
@@ -59,6 +60,7 @@ public class ZipParameters {
this.lastModifiedFileTime = zipParameters.getLastModifiedFileTime();
this.entrySize = zipParameters.getEntrySize();
this.writeExtendedLocalFileHeader = zipParameters.isWriteExtendedLocalFileHeader();
+ this.overrideExistingFilesInZip = zipParameters.isOverrideExistingFilesInZip();
}
public CompressionMethod getCompressionMethod() {
@@ -188,4 +190,12 @@ public class ZipParameters {
public void setWriteExtendedLocalFileHeader(boolean writeExtendedLocalFileHeader) {
this.writeExtendedLocalFileHeader = writeExtendedLocalFileHeader;
}
+
+ public boolean isOverrideExistingFilesInZip() {
+ return overrideExistingFilesInZip;
+ }
+
+ public void setOverrideExistingFilesInZip(boolean overrideExistingFilesInZip) {
+ this.overrideExistingFilesInZip = overrideExistingFilesInZip;
+ }
}
=====================================
src/main/java/net/lingala/zip4j/tasks/AbstractAddFileToZipTask.java
=====================================
@@ -17,6 +17,7 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.util.ArrayList;
import java.util.List;
import static net.lingala.zip4j.headers.HeaderUtil.getFileHeader;
@@ -49,14 +50,14 @@ public abstract class AbstractAddFileToZipTask<T> extends AsyncZipTask<T> {
void addFilesToZip(List<File> filesToAdd, ProgressMonitor progressMonitor, ZipParameters zipParameters)
throws IOException {
- removeFilesIfExists(filesToAdd, zipParameters, progressMonitor);
+ List<File> updatedFilesToAdd = removeFilesIfExists(filesToAdd, zipParameters, progressMonitor);
try (SplitOutputStream splitOutputStream = new SplitOutputStream(zipModel.getZipFile(), zipModel.getSplitLength());
ZipOutputStream zipOutputStream = initializeOutputStream(splitOutputStream)) {
byte[] readBuff = new byte[BUFF_SIZE];
int readLen = -1;
- for (File fileToAdd : filesToAdd) {
+ for (File fileToAdd : updatedFilesToAdd) {
verifyIfTaskIsCancelled();
ZipParameters clonedZipParameters = cloneAndAdjustZipParameters(zipParameters, fileToAdd, progressMonitor);
progressMonitor.setFileName(fileToAdd.getAbsolutePath());
@@ -184,10 +185,12 @@ public abstract class AbstractAddFileToZipTask<T> extends AsyncZipTask<T> {
return clonedZipParameters;
}
- private void removeFilesIfExists(List<File> files, ZipParameters zipParameters, ProgressMonitor progressMonitor)
+ private List<File> removeFilesIfExists(List<File> files, ZipParameters zipParameters, ProgressMonitor progressMonitor)
throws ZipException {
+
+ List<File> filesToAdd = new ArrayList<>(files);
if (!zipModel.getZipFile().exists()) {
- return;
+ return filesToAdd;
}
for (File file : files) {
@@ -195,12 +198,18 @@ public abstract class AbstractAddFileToZipTask<T> extends AsyncZipTask<T> {
FileHeader fileHeader = getFileHeader(zipModel, fileName);
if (fileHeader != null) {
- progressMonitor.setCurrentTask(REMOVE_ENTRY);
- removeFile(fileHeader, progressMonitor);
- verifyIfTaskIsCancelled();
- progressMonitor.setCurrentTask(ADD_ENTRY);
+ if (zipParameters.isOverrideExistingFilesInZip()) {
+ progressMonitor.setCurrentTask(REMOVE_ENTRY);
+ removeFile(fileHeader, progressMonitor);
+ verifyIfTaskIsCancelled();
+ progressMonitor.setCurrentTask(ADD_ENTRY);
+ } else {
+ filesToAdd.remove(file);
+ }
}
}
+
+ return filesToAdd;
}
private void removeFile(FileHeader fileHeader, ProgressMonitor progressMonitor) throws ZipException {
=====================================
src/main/java/net/lingala/zip4j/tasks/AbstractExtractFileTask.java
=====================================
@@ -39,7 +39,7 @@ public abstract class AbstractExtractFileTask<T> extends AsyncZipTask<T> {
// make sure no file is extracted outside of the target directory (a.k.a zip slip)
String fileName = fileHeader.getFileName();
String completePath = outPath + fileName;
- if (!new File(completePath).getPath().startsWith(new File(outPath).getPath())) {
+ if (!new File(completePath).getCanonicalPath().startsWith(new File(outPath).getPath())) {
throw new ZipException("illegal file name that breaks out of the target directory: "
+ fileHeader.getFileName());
}
@@ -72,6 +72,11 @@ public abstract class AbstractExtractFileTask<T> extends AsyncZipTask<T> {
progressMonitor.updateWorkCompleted(readLength);
verifyIfTaskIsCancelled();
}
+ } catch (Exception e) {
+ if (outputFile.exists()) {
+ outputFile.delete();
+ }
+ throw e;
}
UnzipUtil.applyFileAttributes(fileHeader, outputFile);
=====================================
src/main/java/net/lingala/zip4j/util/UnzipUtil.java
=====================================
@@ -17,9 +17,11 @@ import static net.lingala.zip4j.util.FileUtils.setFileLastModifiedTimeWithoutNio
public class UnzipUtil {
public static ZipInputStream createZipInputStream(ZipModel zipModel, FileHeader fileHeader, char[] password)
- throws ZipException {
+ throws IOException {
+
+ SplitInputStream splitInputStream = null;
try {
- SplitInputStream splitInputStream = new SplitInputStream(zipModel.getZipFile(), zipModel.isSplitArchive(),
+ splitInputStream = new SplitInputStream(zipModel.getZipFile(), zipModel.isSplitArchive(),
zipModel.getEndOfCentralDirectoryRecord().getNumberOfThisDisk());
splitInputStream.prepareExtractionForFileHeader(fileHeader);
@@ -30,7 +32,10 @@ public class UnzipUtil {
return zipInputStream;
} catch (IOException e) {
- throw new ZipException(e);
+ if (splitInputStream != null) {
+ splitInputStream.close();
+ }
+ throw e;
}
}
=====================================
src/test/java/net/lingala/zip4j/AddFilesToZipIT.java
=====================================
@@ -150,6 +150,24 @@ public class AddFilesToZipIT extends AbstractIT {
null, null);
}
+ @Test
+ public void testAddFileDoesNotOverrideFileIfFlagIsDisabled() throws IOException {
+ ZipFile zipFile = new ZipFile(generatedZipFile);
+ zipFile.addFiles(FILES_TO_ADD);
+
+ ZipParameters zipParameters = new ZipParameters();
+ zipParameters.setCompressionMethod(CompressionMethod.STORE);
+ zipParameters.setEncryptFiles(true);
+ zipParameters.setEncryptionMethod(EncryptionMethod.AES);
+ zipParameters.setOverrideExistingFilesInZip(false);
+ zipFile.setPassword(PASSWORD);
+ zipFile.addFile(TestUtils.getTestFileFromResources("sample_text_large.txt"), zipParameters);
+
+ ZipFileVerifier.verifyZipFileByExtractingAllFiles(generatedZipFile, outputFolder, 3);
+ verifyZipFileContainsFiles(generatedZipFile, singletonList("sample_text_large.txt"), CompressionMethod.DEFLATE,
+ null, null);
+ }
+
@Test
public void testAddFileRemovesExistingFileNoEncryptionSingleFileInZip() throws IOException {
ZipFile zipFile = new ZipFile(generatedZipFile);
@@ -176,7 +194,7 @@ public class AddFilesToZipIT extends AbstractIT {
assertThat(zipFile.getFileHeaders()).hasSize(1);
assertThat(zipFile.getFileHeader("/data/newfile.txt")).isNotNull();
assertThat(zipFile.getFileHeader("sample_text_large.txt")).isNull();
- zipFile.extractAll(outputFolder.getPath());
+ zipFile.extractAll(outputFolder.getCanonicalPath());
}
@Test
=====================================
src/test/java/net/lingala/zip4j/CreateZipFileIT.java
=====================================
@@ -225,6 +225,17 @@ public class CreateZipFileIT extends AbstractIT {
verifySplitZip(generatedZipFile, 15, InternalZipConstants.MIN_SPLIT_LENGTH + 2000);
}
+ @Test
+ public void testCreateZipFileWithSetPasswordSetter() throws IOException {
+ ZipParameters zipParameters = createZipParameters(EncryptionMethod.AES, AesKeyStrength.KEY_STRENGTH_128);
+
+ ZipFile zipFile = new ZipFile(generatedZipFile, "WRONG_PASSWORD".toCharArray());
+ zipFile.setPassword(PASSWORD);
+ zipFile.addFiles(FILES_TO_ADD, zipParameters);
+
+ verifyZipFileByExtractingAllFiles(generatedZipFile, PASSWORD, outputFolder, FILES_TO_ADD.size());
+ }
+
private void verifySplitZip(File zipFile, int numberOfExpectedSplitFiles, long splitLength) throws ZipException {
assertNumberOfSplitFile(zipFile, numberOfExpectedSplitFiles);
assertSplitFileSizes(zipFile, numberOfExpectedSplitFiles, splitLength);
=====================================
src/test/java/net/lingala/zip4j/ExtractZipFileIT.java
=====================================
@@ -34,7 +34,7 @@ public class ExtractZipFileIT extends AbstractIT {
ZipFile zipFile = new ZipFile(generatedZipFile);
zipFile.addFiles(FILES_TO_ADD, zipParameters);
- zipFile.extractAll(outputFolder.getPath());
+ zipFile.extractAll(outputFolder.getCanonicalPath());
ZipFileVerifier.verifyFolderContentsSameAsSourceFiles(outputFolder);
verifyNumberOfFilesInOutputFolder(outputFolder, 3);
@@ -47,7 +47,7 @@ public class ExtractZipFileIT extends AbstractIT {
ZipFile zipFile = new ZipFile(generatedZipFile, PASSWORD);
zipFile.addFiles(FILES_TO_ADD, zipParameters);
- zipFile.extractAll(outputFolder.getPath());
+ zipFile.extractAll(outputFolder.getCanonicalPath());
ZipFileVerifier.verifyFolderContentsSameAsSourceFiles(outputFolder);
verifyNumberOfFilesInOutputFolder(outputFolder, 3);
@@ -60,7 +60,7 @@ public class ExtractZipFileIT extends AbstractIT {
ZipFile zipFile = new ZipFile(generatedZipFile, PASSWORD);
zipFile.addFiles(FILES_TO_ADD, zipParameters);
- zipFile.extractAll(outputFolder.getPath());
+ zipFile.extractAll(outputFolder.getCanonicalPath());
ZipFileVerifier.verifyFolderContentsSameAsSourceFiles(outputFolder);
verifyNumberOfFilesInOutputFolder(outputFolder, 3);
@@ -73,7 +73,7 @@ public class ExtractZipFileIT extends AbstractIT {
ZipFile zipFile = new ZipFile(generatedZipFile, PASSWORD);
zipFile.addFiles(FILES_TO_ADD, zipParameters);
- zipFile.extractAll(outputFolder.getPath());
+ zipFile.extractAll(outputFolder.getCanonicalPath());
ZipFileVerifier.verifyFolderContentsSameAsSourceFiles(outputFolder);
verifyNumberOfFilesInOutputFolder(outputFolder, 3);
@@ -84,7 +84,7 @@ public class ExtractZipFileIT extends AbstractIT {
ZipFile zipFile = new ZipFile(generatedZipFile);
zipFile.addFiles(FILES_TO_ADD);
- zipFile.extractAll(outputFolder.getPath());
+ zipFile.extractAll(outputFolder.getCanonicalPath());
ZipFileVerifier.verifyFolderContentsSameAsSourceFiles(outputFolder);
verifyNumberOfFilesInOutputFolder(outputFolder, 3);
@@ -96,7 +96,7 @@ public class ExtractZipFileIT extends AbstractIT {
ZipFile zipFile = new ZipFile(generatedZipFile, PASSWORD);
zipFile.addFiles(FILES_TO_ADD, zipParameters);
- zipFile.extractAll(outputFolder.getPath());
+ zipFile.extractAll(outputFolder.getCanonicalPath());
ZipFileVerifier.verifyFolderContentsSameAsSourceFiles(outputFolder);
verifyNumberOfFilesInOutputFolder(outputFolder, 3);
@@ -108,7 +108,7 @@ public class ExtractZipFileIT extends AbstractIT {
ZipFile zipFile = new ZipFile(generatedZipFile, PASSWORD);
zipFile.addFiles(FILES_TO_ADD, zipParameters);
- zipFile.extractAll(outputFolder.getPath());
+ zipFile.extractAll(outputFolder.getCanonicalPath());
ZipFileVerifier.verifyFolderContentsSameAsSourceFiles(outputFolder);
verifyNumberOfFilesInOutputFolder(outputFolder, 3);
@@ -120,7 +120,7 @@ public class ExtractZipFileIT extends AbstractIT {
ZipFile zipFile = new ZipFile(generatedZipFile, PASSWORD);
zipFile.addFiles(FILES_TO_ADD, zipParameters);
- zipFile.extractAll(outputFolder.getPath());
+ zipFile.extractAll(outputFolder.getCanonicalPath());
ZipFileVerifier.verifyFolderContentsSameAsSourceFiles(outputFolder);
verifyNumberOfFilesInOutputFolder(outputFolder, 3);
@@ -133,7 +133,7 @@ public class ExtractZipFileIT extends AbstractIT {
zipFile.addFiles(FILES_TO_ADD, zipParameters);
FileHeader fileHeader = zipFile.getFileHeader("sample_text_large.txt");
- zipFile.extractFile(fileHeader, outputFolder.getPath());
+ zipFile.extractFile(fileHeader, outputFolder.getCanonicalPath());
File[] outputFiles = outputFolder.listFiles();
assertThat(outputFiles).hasSize(1);
@@ -147,7 +147,7 @@ public class ExtractZipFileIT extends AbstractIT {
zipFile.addFolder(TestUtils.getTestFileFromResources(""), zipParameters);
FileHeader fileHeader = zipFile.getFileHeader("test-files/öüäöäö/asöäööl");
- zipFile.extractFile(fileHeader, outputFolder.getPath());
+ zipFile.extractFile(fileHeader, outputFolder.getCanonicalPath());
File outputFile = getFileWithNameFrom(outputFolder, "asöäööl");
ZipFileVerifier.verifyFileContent(TestUtils.getTestFileFromResources("öüäöäö/asöäööl"), outputFile);
@@ -161,7 +161,7 @@ public class ExtractZipFileIT extends AbstractIT {
String newFileName = "newFileName";
FileHeader fileHeader = zipFile.getFileHeader("sample_text_large.txt");
- zipFile.extractFile(fileHeader, outputFolder.getPath(), newFileName);
+ zipFile.extractFile(fileHeader, outputFolder.getCanonicalPath(), newFileName);
File outputFile = getFileWithNameFrom(outputFolder, newFileName);
ZipFileVerifier.verifyFileContent(TestUtils.getTestFileFromResources("sample_text_large.txt"), outputFile);
@@ -184,7 +184,7 @@ public class ExtractZipFileIT extends AbstractIT {
ZipFile zipFile = new ZipFile(generatedZipFile, PASSWORD);
zipFile.addFolder(TestUtils.getTestFileFromResources(""), zipParameters);
- zipFile.extractFile("test-files/sample_directory/favicon.ico", outputFolder.getPath());
+ zipFile.extractFile("test-files/sample_directory/favicon.ico", outputFolder.getCanonicalPath());
File outputFile = getFileWithNameFrom(outputFolder, "favicon.ico");
ZipFileVerifier.verifyFileContent(TestUtils.getTestFileFromResources("sample_directory/favicon.ico"), outputFile);
@@ -197,21 +197,21 @@ public class ExtractZipFileIT extends AbstractIT {
zipFile.addFolder(TestUtils.getTestFileFromResources(""), zipParameters);
String newFileName = "newFileName";
- zipFile.extractFile("test-files/sample_directory/favicon.ico", outputFolder.getPath(), newFileName);
+ zipFile.extractFile("test-files/sample_directory/favicon.ico", outputFolder.getCanonicalPath(), newFileName);
File outputFile = getFileWithNameFrom(outputFolder, newFileName);
ZipFileVerifier.verifyFileContent(TestUtils.getTestFileFromResources("sample_directory/favicon.ico"), outputFile);
}
@Test
- public void testExtractFilesThrowsExceptionForWrongPasswordForAes() throws ZipException {
+ public void testExtractFilesThrowsExceptionForWrongPasswordForAes() throws IOException {
ZipParameters zipParameters = createZipParameters(EncryptionMethod.AES, AesKeyStrength.KEY_STRENGTH_256);
ZipFile zipFile = new ZipFile(generatedZipFile, PASSWORD);
zipFile.addFiles(FILES_TO_ADD, zipParameters);
try {
zipFile = new ZipFile(generatedZipFile, "WRONG_PASSWORD".toCharArray());
- zipFile.extractAll(outputFolder.getPath());
+ zipFile.extractAll(outputFolder.getCanonicalPath());
fail("Should throw an exception");
} catch (ZipException e) {
assertThat(e).isNotNull();
@@ -220,14 +220,14 @@ public class ExtractZipFileIT extends AbstractIT {
}
@Test
- public void testExtractFilesThrowsExceptionForWrongPasswordForZipStandardAndDeflate() throws ZipException {
+ public void testExtractFilesThrowsExceptionForWrongPasswordForZipStandardAndDeflate() throws IOException {
ZipParameters zipParameters = createZipParameters(EncryptionMethod.ZIP_STANDARD, null);
ZipFile zipFile = new ZipFile(generatedZipFile, PASSWORD);
zipFile.addFiles(FILES_TO_ADD, zipParameters);
try {
zipFile = new ZipFile(generatedZipFile, "WRONG_PASSWORD".toCharArray());
- zipFile.extractAll(outputFolder.getPath());
+ zipFile.extractAll(outputFolder.getCanonicalPath());
fail("Should throw an exception");
} catch (ZipException e) {
assertThat(e).isNotNull();
@@ -236,7 +236,7 @@ public class ExtractZipFileIT extends AbstractIT {
}
@Test
- public void testExtractFilesThrowsExceptionForWrongPasswordForZipStandardAndStore() throws ZipException {
+ public void testExtractFilesThrowsExceptionForWrongPasswordForZipStandardAndStore() throws IOException {
ZipParameters zipParameters = createZipParameters(EncryptionMethod.ZIP_STANDARD, null);
zipParameters.setCompressionMethod(CompressionMethod.STORE);
ZipFile zipFile = new ZipFile(generatedZipFile, PASSWORD);
@@ -244,7 +244,7 @@ public class ExtractZipFileIT extends AbstractIT {
try {
zipFile = new ZipFile(generatedZipFile, "WRONG_PASSWORD".toCharArray());
- zipFile.extractAll(outputFolder.getPath());
+ zipFile.extractAll(outputFolder.getCanonicalPath());
fail("Should throw an exception");
} catch (ZipException e) {
assertThat(e).isNotNull();
@@ -263,12 +263,23 @@ public class ExtractZipFileIT extends AbstractIT {
public void testExtractFilesForZipFileWhileWithCorruptExtraDataRecordLength() throws IOException {
ZipFile zipFile = new ZipFile(getTestArchiveFromResources("corrupt_extra_data_record_length.zip"));
- zipFile.extractAll(outputFolder.getPath());
+ zipFile.extractAll(outputFolder.getCanonicalPath());
assertThat(zipFile.getFileHeaders()).hasSize(44);
assertThat(Files.walk(outputFolder.toPath()).filter(Files::isRegularFile)).hasSize(44);
}
+ @Test
+ public void testExtractFilesWithSetPasswordSetter() throws IOException {
+ ZipParameters zipParameters = createZipParameters(EncryptionMethod.ZIP_STANDARD, null);
+ ZipFile zipFile = new ZipFile(generatedZipFile, PASSWORD);
+ zipFile.addFiles(FILES_TO_ADD, zipParameters);
+
+ zipFile = new ZipFile(generatedZipFile, "WRONG_PASSWORD".toCharArray());
+ zipFile.setPassword(PASSWORD);
+ zipFile.extractAll(outputFolder.getCanonicalPath());
+ }
+
private void verifyNumberOfFilesInOutputFolder(File outputFolder, int numberOfExpectedFiles) {
assertThat(outputFolder.listFiles()).hasSize(numberOfExpectedFiles);
}
=====================================
src/test/java/net/lingala/zip4j/MiscZipFileIT.java
=====================================
@@ -23,6 +23,7 @@ import java.util.List;
import java.util.stream.Collectors;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.fail;
public class MiscZipFileIT extends AbstractIT {
@@ -384,10 +385,47 @@ public class MiscZipFileIT extends AbstractIT {
File newFile = temporaryFolder.newFile("NEW_FILE_NAME.ZIP");
String oldFile = generatedZipFile.getPath();
+ if(TestUtils.isWindows())
+ {
+ newFile.delete();
+ }
+
assertThat(generatedZipFile.renameTo(newFile)).isTrue();
assertThat(new File(oldFile)).doesNotExist();
}
+ @Test
+ public void testZipSlipFix() throws Exception {
+ ZipParameters zipParameters = new ZipParameters();
+ zipParameters.setFileNameInZip("../../bad.txt");
+
+ ZipFile zip = new ZipFile(generatedZipFile);
+ zip.addFile(TestUtils.getTestFileFromResources("sample_text1.txt"), zipParameters);
+
+ try {
+ zip.extractAll(outputFolder.getAbsolutePath());
+ fail("zip4j is vulnerable for slip zip");
+ } catch (ZipException e) {
+ assertThat(e).hasMessageStartingWith("illegal file name that breaks out of the target directory: ");
+ }
+ }
+
+ @Test
+ public void testExtractFileDeletesOutputFileWhenWrongPassword() throws IOException {
+ ZipParameters zipParameters = createZipParameters(EncryptionMethod.ZIP_STANDARD, AesKeyStrength.KEY_STRENGTH_256);
+ ZipFile zipFile = new ZipFile(generatedZipFile, PASSWORD);
+ zipFile.addFile(TestUtils.getTestFileFromResources("sample_text1.txt"), zipParameters);
+
+ try {
+ zipFile = new ZipFile(generatedZipFile, "WRONG_PASSWORD".toCharArray());
+ zipFile.extractAll(outputFolder.getCanonicalPath());
+ fail("Should throw an exception");
+ } catch (ZipException e) {
+ assertThat(new File(outputFolder.getCanonicalPath() + "sample_text1.txt")).doesNotExist();
+ assertThat(e.getType()).isEqualTo(ZipException.Type.WRONG_PASSWORD);
+ }
+ }
+
private void verifyInputStream(InputStream inputStream, File fileToCompareAgainst) throws IOException {
File outputFile = temporaryFolder.newFile();
try (OutputStream outputStream = new FileOutputStream(outputFile)) {
=====================================
src/test/java/net/lingala/zip4j/ZipFileTest.java
=====================================
@@ -11,6 +11,7 @@ import org.junit.rules.ExpectedException;
import java.io.ByteArrayInputStream;
import java.io.File;
+import java.io.IOException;
import java.util.Collections;
import static org.assertj.core.api.Assertions.assertThat;
@@ -398,6 +399,13 @@ public class ZipFileTest {
zipFile.extractFile("", "SOME_DESTINATION");
}
+ @Test
+ public void testGetFileHeadersReturnsEmptyListWhenZipFileDoesNotExist() throws ZipException {
+ File mockFile = mockFile(false);
+ ZipFile zipFile = new ZipFile(mockFile);
+ assertThat(zipFile.getFileHeaders()).isEmpty();
+ }
+
@Test
public void testGetFileHeaderThrowsExceptionWhenFileNameIsNull() throws ZipException {
expectedException.expectMessage("input file name is emtpy or null, cannot get FileHeader");
@@ -481,7 +489,7 @@ public class ZipFileTest {
}
@Test
- public void testGetInputStreamWhenFileHeaderIsNullThrowsException() throws ZipException {
+ public void testGetInputStreamWhenFileHeaderIsNullThrowsException() throws IOException {
expectedException.expectMessage("FileHeader is null, cannot get InputStream");
expectedException.expect(ZipException.class);
=====================================
src/test/java/net/lingala/zip4j/headers/HeaderUtilTest.java
=====================================
@@ -20,8 +20,6 @@ public class HeaderUtilTest {
private static final String FILE_NAME = "test.txt";
- private HeaderUtil headerUtil = new HeaderUtil();
-
@Rule
public ExpectedException expectedException = ExpectedException.none();
=====================================
src/test/java/net/lingala/zip4j/io/inputstream/ZipInputStreamIT.java
=====================================
@@ -161,6 +161,17 @@ public class ZipInputStreamIT extends AbstractIT {
zipInputStream.close();
}
+ @Test
+ public void testGetNextEntryReturnsNextEntryEvenIfEntryNotCompletelyRead() throws IOException {
+ File createZipFile = createZipFile(CompressionMethod.DEFLATE);
+ ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(createZipFile));
+ int numberOfEntries = 0;
+ while (zipInputStream.getNextEntry() != null) {
+ numberOfEntries++;
+ }
+ assertThat(numberOfEntries).isEqualTo(FILES_TO_ADD.size());
+ }
+
private void extractZipFileWithInputStreams(File zipFile, char[] password) throws IOException {
extractZipFileWithInputStreams(zipFile, password, 4096, AesVersion.TWO);
}
=====================================
src/test/java/net/lingala/zip4j/testutils/TestUtils.java
=====================================
@@ -18,6 +18,11 @@ public class TestUtils {
return getFileFromResources(TEST_ARCHIVES_FOLDER_NAME, fileName);
}
+ public static Boolean isWindows() {
+ String os = System.getProperty("os.name").toLowerCase();
+ return (os.contains("win"));
+ }
+
private static File getFileFromResources(String parentFolder, String fileName) {
try {
String path = "/" + parentFolder + "/" + fileName;
=====================================
src/test/java/net/lingala/zip4j/testutils/ZipFileVerifier.java
=====================================
@@ -1,7 +1,6 @@
package net.lingala.zip4j.testutils;
import net.lingala.zip4j.ZipFile;
-import net.lingala.zip4j.model.LocalFileHeader;
import net.lingala.zip4j.progress.ProgressMonitor;
import net.lingala.zip4j.util.CrcUtil;
import net.lingala.zip4j.util.FileUtils;
@@ -10,7 +9,6 @@ import java.io.File;
import java.io.IOException;
import java.util.List;
-import static net.lingala.zip4j.util.BitUtils.isBitSet;
import static org.assertj.core.api.Assertions.assertThat;
public class ZipFileVerifier {
@@ -33,7 +31,7 @@ public class ZipFileVerifier {
assertThat(zipFileToExtract).exists();
ZipFile zipFile = new ZipFile(zipFileToExtract, password);
- zipFile.extractAll(outputFolder.getPath());
+ zipFile.extractAll(outputFolder.getCanonicalPath());
assertThat(zipFile.getFileHeaders().size()).as("Number of file headers").isEqualTo(expectedNumberOfEntries);
List<File> extractedFiles = FileUtils.getFilesInDirectoryRecursive(outputFolder, true, true);
@@ -62,13 +60,6 @@ public class ZipFileVerifier {
}
}
- private static long getUncompressedSize(LocalFileHeader localFileHeader) {
- if (localFileHeader.getZip64ExtendedInfo() != null && !isBitSet(localFileHeader.getGeneralPurposeFlag()[0], 3)) {
- return localFileHeader.getZip64ExtendedInfo().getUncompressedSize();
- }
- return localFileHeader.getUncompressedSize();
- }
-
private static void verifyFileCrc(File sourceFile, File extractedFile) throws IOException {
ProgressMonitor progressMonitor = new ProgressMonitor();
long sourceFileCrc = CrcUtil.computeFileCrc(sourceFile, progressMonitor);
=====================================
src/test/java/net/lingala/zip4j/util/CrcUtilIT.java
=====================================
@@ -23,7 +23,6 @@ public class CrcUtilIT extends AbstractIT {
@Rule
public ExpectedException expectedException = ExpectedException.none();
- private CrcUtil crcUtil = new CrcUtil();
private ProgressMonitor progressMonitor = new ProgressMonitor();
@Test
=====================================
src/test/java/net/lingala/zip4j/util/FileUtilsTest.java
=====================================
@@ -157,14 +157,18 @@ public class FileUtilsTest {
@Test
public void testGetZipFileNameWithoutExtensionForWindowsFileSeparator() throws ZipException {
+ final String ACTUAL_FILE_SEPARATOR = System.getProperty("file.separator");
System.setProperty("file.separator", "\\");
assertThat(FileUtils.getZipFileNameWithoutExtension("c:\\mydir\\somefile.zip")).isEqualTo("somefile");
+ System.setProperty("file.separator", ACTUAL_FILE_SEPARATOR);
}
@Test
public void testGetZipFileNameWithoutExtensionForUnixFileSeparator() throws ZipException {
+ final String ACTUAL_FILE_SEPARATOR = System.getProperty("file.separator");
System.setProperty("file.separator", "/");
assertThat(FileUtils.getZipFileNameWithoutExtension("/usr/srikanth/somezip.zip")).isEqualTo("somezip");
+ System.setProperty("file.separator", ACTUAL_FILE_SEPARATOR);
}
@Test
@@ -223,7 +227,8 @@ public class FileUtilsTest {
@Test
public void testGetSplitZipFilesReturnsValidWhenSplitFile() throws ZipException {
- String path = "/usr/parentdir/";
+ final String FILE_SEPARATOR = System.getProperty("file.separator");
+ String path = FILE_SEPARATOR + "usr" + FILE_SEPARATOR + "parentdir" + FILE_SEPARATOR;
String zipFileName = "SomeName";
File zipFile = mockZipFileAsExists(path, zipFileName);
ZipModel zipModel = new ZipModel();
View it on GitLab: https://salsa.debian.org/java-team/zip4j/commit/40f527130037cabb217f2cd995fb9f40e8c55cc5
--
View it on GitLab: https://salsa.debian.org/java-team/zip4j/commit/40f527130037cabb217f2cd995fb9f40e8c55cc5
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-java-commits/attachments/20190912/d45fe955/attachment.html>
More information about the pkg-java-commits
mailing list