[Git][java-team/zip4j][upstream] New upstream version 2.6.0
Andrius Merkys
gitlab at salsa.debian.org
Mon May 25 05:34:29 BST 2020
Andrius Merkys pushed to branch upstream at Debian Java Maintainers / zip4j
Commits:
a7171185 by Andrius Merkys at 2020-05-25T00:12:12-04:00
New upstream version 2.6.0
- - - - -
30 changed files:
- .travis.yml
- README.md
- pom.xml
- src/main/java/net/lingala/zip4j/ZipFile.java
- src/main/java/net/lingala/zip4j/headers/FileHeaderFactory.java
- src/main/java/net/lingala/zip4j/headers/HeaderUtil.java
- + src/main/java/net/lingala/zip4j/headers/VersionMadeBy.java
- + src/main/java/net/lingala/zip4j/headers/VersionNeededToExtract.java
- src/main/java/net/lingala/zip4j/io/outputstream/ZipOutputStream.java
- + src/main/java/net/lingala/zip4j/model/ExcludeFileFilter.java
- src/main/java/net/lingala/zip4j/model/ZipParameters.java
- src/main/java/net/lingala/zip4j/model/enums/AesKeyStrength.java
- src/main/java/net/lingala/zip4j/model/enums/AesVersion.java
- src/main/java/net/lingala/zip4j/model/enums/CompressionLevel.java
- src/main/java/net/lingala/zip4j/model/enums/CompressionMethod.java
- src/main/java/net/lingala/zip4j/model/enums/EncryptionMethod.java
- src/main/java/net/lingala/zip4j/tasks/AddFolderToZipTask.java
- src/main/java/net/lingala/zip4j/tasks/ExtractAllFilesTask.java
- src/main/java/net/lingala/zip4j/tasks/ExtractFileTask.java
- src/main/java/net/lingala/zip4j/util/FileUtils.java
- + src/main/java/net/lingala/zip4j/util/ZipVersionUtils.java
- src/test/java/net/lingala/zip4j/AddFilesToZipIT.java
- src/test/java/net/lingala/zip4j/ExtractZipFileIT.java
- src/test/java/net/lingala/zip4j/headers/FileHeaderFactoryTest.java
- src/test/java/net/lingala/zip4j/headers/HeaderReaderIT.java
- src/test/java/net/lingala/zip4j/headers/HeaderUtilTest.java
- src/test/java/net/lingala/zip4j/util/FileUtilsIT.java
- src/test/java/net/lingala/zip4j/util/FileUtilsTestLinuxAndMac.java
- src/test/java/net/lingala/zip4j/util/FileUtilsTestWindows.java
- + src/test/java/net/lingala/zip4j/util/ZipVersionUtilsTest.java
Changes:
=====================================
.travis.yml
=====================================
@@ -1,7 +1,7 @@
language: java
before_script:
- - bash trigger-android-build.sh ${CIRCLE_CI_TOKEN} || travis_terminate 1;
+ - 'if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then bash trigger-android-build.sh ${CIRCLE_CI_TOKEN} || travis_terminate 1; fi'
script:
- travis_wait 30 mvn clean verify
=====================================
README.md
=====================================
@@ -62,7 +62,7 @@ once again, and makes me support Zip4j as much as I can..
<dependency>
<groupId>net.lingala.zip4j</groupId>
<artifactId>zip4j</artifactId>
- <version>2.5.2</version>
+ <version>2.6.0</version>
</dependency>
~~~~
@@ -94,6 +94,14 @@ new ZipFile("filename.zip").addFiles(Arrays.asList(new File("first_file"), new F
new ZipFile("filename.zip").addFolder(new File("/user/myuser/folder_to_add"));
~~~~
+Since v2.6, it is possible to exclude certain files when adding a folder to zip by using an ExcludeFileFilter
+
+~~~~
+List<File> filesToExclude = Arrays.asList(new File("sample.pdf"), new File("sample_2.txt"));
+ExcludeFileFilter excludeFileFilter = filesToExclude::contains;
+new ZipFile("filename.zip").addFolder(new File("/user/myuser/folder_to_add"), new ZipParameters, excludeFileFilter);
+~~~~
+
### Creating a zip file from stream / Adding a stream to an existing zip
~~~~
@@ -211,17 +219,26 @@ new ZipFile("filename.zip", "password".toCharArray()).extractAll("/destination_d
new ZipFile("filename.zip").extractFile("fileNameInZip.txt", "/destination_directory");
~~~~
+### Extracting a folder from zip (since v2.6.0)
+
+~~~~
+new ZipFile("filename.zip").extractFile("folderNameInZip/", "/destination_directory");
+~~~~
+
### Extracting a single file from zip which is password protected
~~~~
new ZipFile("filename.zip", "password".toCharArray()).extractFile("fileNameInZip.txt", "/destination_directory");
~~~~
+Since v2.6.0: If the file name represents a directory, zip4j will extract all files in the zip that are part of this directory.
+
### Extracting a single file from zip and giving it a new file name
Below example will extract the file `fileNameInZip.txt` from the zip file to the output directory `/destination_directory`
and will give the file a name `newfileName.txt`. Without the third parameter of the new file name, the same name as the
-file in the zip will be used, which in this case is `fileNameInZip.txt`
+file in the zip will be used, which in this case is `fileNameInZip.txt`. If the file being extracted is a directory,
+`newFileName` parameter will be used as the directory name.
~~~~
new ZipFile("filename.zip", "password".toCharArray()).extractFile("fileNameInZip.txt", "/destination_directory", "newfileName.txt");
=====================================
pom.xml
=====================================
@@ -6,7 +6,7 @@
<groupId>net.lingala.zip4j</groupId>
<artifactId>zip4j</artifactId>
- <version>2.5.3-SNAPSHOT</version>
+ <version>2.6.1-SNAPSHOT</version>
<name>Zip4j</name>
<description>Zip4j - A Java library for zip files and streams</description>
=====================================
src/main/java/net/lingala/zip4j/ZipFile.java
=====================================
@@ -181,7 +181,6 @@ public class ZipFile {
*/
public void createSplitZipFileFromFolder(File folderToAdd, ZipParameters parameters, boolean splitArchive,
long splitLength) throws ZipException {
-
if (folderToAdd == null) {
throw new ZipException("folderToAdd is null, cannot create zip file from folder");
}
@@ -454,9 +453,7 @@ public class ZipFile {
* Extracts a specific file from the zip file to the destination path.
* If destination path is invalid, then this method throws an exception.
* <br><br>
- * If newFileName is not null or empty, newly created file name will be replaced by
- * the value in newFileName. If this value is null, then the file name will be the
- * value in FileHeader.getFileName
+ * If fileHeader is a directory, this method extracts all files under this directory
*
* @param fileHeader
* @param destinationPath
@@ -469,6 +466,13 @@ public class ZipFile {
/**
* Extracts a specific file from the zip file to the destination path.
* If destination path is invalid, then this method throws an exception.
+ * <br><br>
+ * If newFileName is not null or empty, newly created file name will be replaced by
+ * the value in newFileName. If this value is null, then the file name will be the
+ * value in FileHeader.getFileName. If file being extract is a directory, the directory name
+ * will be replaced with the newFileName
+ * <br><br>
+ * If fileHeader is a directory, this method extracts all files under this directory.
*
* @param fileHeader
* @param destinationPath
@@ -503,6 +507,8 @@ public class ZipFile {
* example is if there is a file "b.txt" in a folder "abc" in the zip file, then the
* input file name has to be abc/b.txt
* <br><br>
+ * If fileHeader is a directory, this method extracts all files under this directory.
+ * <br><br>
* Throws an exception of type {@link ZipException.Type#FILE_NOT_FOUND} if file header could not be found for the given file name.
* Throws an exception if the destination path is invalid.
*
@@ -525,7 +531,10 @@ public class ZipFile {
* <br><br>
* If newFileName is not null or empty, newly created file name will be replaced by
* the value in newFileName. If this value is null, then the file name will be the
- * value in FileHeader.getFileName
+ * value in FileHeader.getFileName. If file being extract is a directory, the directory name
+ * will be replaced with the newFileName
+ * <br><br>
+ * If fileHeader is a directory, this method extracts all files under this directory.
* <br><br>
* Throws an exception of type {@link ZipException.Type#FILE_NOT_FOUND} if file header could not be found for the given file name.
* Throws an exception if the destination path is invalid.
=====================================
src/main/java/net/lingala/zip4j/headers/FileHeaderFactory.java
=====================================
@@ -10,6 +10,7 @@ import net.lingala.zip4j.model.enums.CompressionLevel;
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.RawIO;
import net.lingala.zip4j.util.Zip4jUtil;
import java.nio.charset.Charset;
@@ -17,16 +18,19 @@ import java.nio.charset.Charset;
import static net.lingala.zip4j.util.BitUtils.setBit;
import static net.lingala.zip4j.util.BitUtils.unsetBit;
import static net.lingala.zip4j.util.FileUtils.isZipEntryDirectory;
+import static net.lingala.zip4j.util.ZipVersionUtils.determineVersionMadeBy;
+import static net.lingala.zip4j.util.ZipVersionUtils.determineVersionNeededToExtract;
public class FileHeaderFactory {
- public FileHeader generateFileHeader(ZipParameters zipParameters, boolean isSplitZip, int currentDiskNumberStart, Charset charset)
+ public FileHeader generateFileHeader(ZipParameters zipParameters, boolean isSplitZip, int currentDiskNumberStart,
+ Charset charset, RawIO rawIO)
throws ZipException {
FileHeader fileHeader = new FileHeader();
fileHeader.setSignature(HeaderSignature.CENTRAL_DIRECTORY);
- fileHeader.setVersionMadeBy(20);
- fileHeader.setVersionNeededToExtract(20);
+ fileHeader.setVersionMadeBy(determineVersionMadeBy(zipParameters, rawIO));
+ fileHeader.setVersionNeededToExtract(determineVersionNeededToExtract(zipParameters).getCode());
if (zipParameters.isEncryptFiles() && zipParameters.getEncryptionMethod() == EncryptionMethod.AES) {
fileHeader.setCompressionMethod(CompressionMethod.AES_INTERNAL_ONLY);
=====================================
src/main/java/net/lingala/zip4j/headers/HeaderUtil.java
=====================================
@@ -7,7 +7,9 @@ import net.lingala.zip4j.util.InternalZipConstants;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
+import java.util.Collections;
import java.util.List;
+import java.util.stream.Collectors;
import static net.lingala.zip4j.util.InternalZipConstants.ZIP_STANDARD_CHARSET;
import static net.lingala.zip4j.util.Zip4jUtil.isStringNotNullAndNotEmpty;
@@ -91,6 +93,27 @@ public class HeaderUtil {
}
}
+ public static List<FileHeader> getFileHeadersUnderDirectory(List<FileHeader> allFileHeaders, FileHeader rootFileHeader) {
+ if (!rootFileHeader.isDirectory()) {
+ return Collections.emptyList();
+ }
+
+ return allFileHeaders.stream().filter(e -> e.getFileName().startsWith(rootFileHeader.getFileName())).collect(Collectors.toList());
+ }
+
+ public static long getTotalUncompressedSizeOfAllFileHeaders(List<FileHeader> fileHeaders) {
+ long totalUncompressedSize = 0;
+ for (FileHeader fileHeader : fileHeaders) {
+ if (fileHeader.getZip64ExtendedInfo() != null &&
+ fileHeader.getZip64ExtendedInfo().getUncompressedSize() > 0) {
+ totalUncompressedSize += fileHeader.getZip64ExtendedInfo().getUncompressedSize();
+ } else {
+ totalUncompressedSize += fileHeader.getUncompressedSize();
+ }
+ }
+ return totalUncompressedSize;
+ }
+
private static long getOffsetOfEndOfCentralDirectory(ZipModel zipModel) {
if (zipModel.isZip64Format()) {
return zipModel.getZip64EndOfCentralDirectoryRecord().getOffsetStartCentralDirectoryWRTStartDiskNumber();
=====================================
src/main/java/net/lingala/zip4j/headers/VersionMadeBy.java
=====================================
@@ -0,0 +1,18 @@
+package net.lingala.zip4j.headers;
+
+public enum VersionMadeBy {
+
+ SPECIFICATION_VERSION((byte) 51),
+ WINDOWS((byte) 0),
+ UNIX((byte) 3);
+
+ private byte code;
+
+ VersionMadeBy(byte code) {
+ this.code = code;
+ }
+
+ public byte getCode() {
+ return code;
+ }
+}
=====================================
src/main/java/net/lingala/zip4j/headers/VersionNeededToExtract.java
=====================================
@@ -0,0 +1,19 @@
+package net.lingala.zip4j.headers;
+
+public enum VersionNeededToExtract {
+
+ DEFAULT(10),
+ DEFLATE_COMPRESSED(20),
+ ZIP_64_FORMAT(45),
+ AES_ENCRYPTED(51);
+
+ private int code;
+
+ VersionNeededToExtract(int code) {
+ this.code = code;
+ }
+
+ public int getCode() {
+ return code;
+ }
+}
=====================================
src/main/java/net/lingala/zip4j/io/outputstream/ZipOutputStream.java
=====================================
@@ -148,7 +148,7 @@ public class ZipOutputStream extends OutputStream {
private void initializeAndWriteFileHeader(ZipParameters zipParameters) throws IOException {
fileHeader = fileHeaderFactory.generateFileHeader(zipParameters, countingOutputStream.isSplitZipFile(),
- countingOutputStream.getCurrentSplitFileCounter(), charset);
+ countingOutputStream.getCurrentSplitFileCounter(), charset, rawIO);
fileHeader.setOffsetLocalHeader(countingOutputStream.getOffsetForNextEntry());
localFileHeader = fileHeaderFactory.generateLocalFileHeader(fileHeader);
=====================================
src/main/java/net/lingala/zip4j/model/ExcludeFileFilter.java
=====================================
@@ -0,0 +1,9 @@
+package net.lingala.zip4j.model;
+
+import java.io.File;
+
+public interface ExcludeFileFilter {
+
+ boolean isExcluded(File file);
+
+}
=====================================
src/main/java/net/lingala/zip4j/model/ZipParameters.java
=====================================
@@ -22,9 +22,28 @@ import net.lingala.zip4j.model.enums.CompressionLevel;
import net.lingala.zip4j.model.enums.CompressionMethod;
import net.lingala.zip4j.model.enums.EncryptionMethod;
+/**
+ * Encapsulates the parameters that that control how Zip4J encodes data
+ */
public class ZipParameters {
- public enum SymbolicLinkAction {INCLUDE_LINK_ONLY, INCLUDE_LINKED_FILE_ONLY, INCLUDE_LINK_AND_LINKED_FILE};
+ /**
+ * Indicates the action to take when a symbolic link is added to the ZIP file
+ */
+ public enum SymbolicLinkAction {
+ /**
+ * Add only the symbolic link itself, not the target file or its contents
+ */
+ INCLUDE_LINK_ONLY,
+ /**
+ * Add only the target file and its contents, using the filename of the symbolic link
+ */
+ INCLUDE_LINKED_FILE_ONLY,
+ /**
+ * Add the symbolic link itself and the target file with its original filename and its contents
+ */
+ INCLUDE_LINK_AND_LINKED_FILE
+ };
private CompressionMethod compressionMethod = CompressionMethod.DEFLATE;
private CompressionLevel compressionLevel = CompressionLevel.NORMAL;
@@ -45,10 +64,23 @@ public class ZipParameters {
private String rootFolderNameInZip;
private String fileComment;
private SymbolicLinkAction symbolicLinkAction = SymbolicLinkAction.INCLUDE_LINKED_FILE_ONLY;
-
+ private ExcludeFileFilter excludeFileFilter;
+ private boolean unixMode;
+
+ /**
+ * Create a ZipParameters instance with default values;
+ * CompressionMethod.DEFLATE, CompressionLevel.NORMAL, EncryptionMethod.NONE,
+ * AesKeyStrength.KEY_STRENGTH_256, AesVerson.Two, SymbolicLinkAction.INCLUDE_LINKED_FILE_ONLY,
+ * readHiddenFiles is true, readHiddenFolders is true, includeRootInFolder is true,
+ * writeExtendedLocalFileHeader is true, overrideExistingFilesInZip is true
+ */
public ZipParameters() {
}
+ /**
+ * Create a clone of given ZipParameters instance
+ * @param zipParameters the ZipParameters instance to clone
+ */
public ZipParameters(ZipParameters zipParameters) {
this.compressionMethod = zipParameters.getCompressionMethod();
this.compressionLevel = zipParameters.getCompressionLevel();
@@ -71,50 +103,101 @@ public class ZipParameters {
this.symbolicLinkAction = zipParameters.getSymbolicLinkAction();
}
+ /**
+ * Get the compression method specified in this ZipParameters
+ * @return the ZIP compression method
+ */
public CompressionMethod getCompressionMethod() {
return compressionMethod;
}
+ /**
+ * Set the ZIP compression method
+ * @param compressionMethod the ZIP compression method
+ */
public void setCompressionMethod(CompressionMethod compressionMethod) {
this.compressionMethod = compressionMethod;
}
+ /**
+ * Test if files files are to be encrypted
+ * @return true if files are to be encrypted
+ */
public boolean isEncryptFiles() {
return encryptFiles;
}
- public void setEncryptFiles(boolean encryptFiles) {
+ /**
+ * Set the flag indicating that files are to be encrypted
+ * @param encryptFiles if true, files will be encrypted
+ */
+public void setEncryptFiles(boolean encryptFiles) {
this.encryptFiles = encryptFiles;
}
+ /**
+ * Get the encryption method used to encrypt files
+ * @return the encryption method
+ */
public EncryptionMethod getEncryptionMethod() {
return encryptionMethod;
}
+ /**
+ * Set the encryption method used to encrypt files
+ * @param encryptionMethod the encryption method to be used
+ */
public void setEncryptionMethod(EncryptionMethod encryptionMethod) {
this.encryptionMethod = encryptionMethod;
}
+ /**
+ * Get the compression level used to compress files
+ * @return the compression level used to compress files
+ */
public CompressionLevel getCompressionLevel() {
return compressionLevel;
}
+ /**
+ * Set the compression level used to compress files
+ * @param compressionLevel the compression level used to compress files
+ */
public void setCompressionLevel(CompressionLevel compressionLevel) {
this.compressionLevel = compressionLevel;
}
+ /**
+ * Test if hidden files will be included during folder recursion
+ *
+ * @return true if hidden files will be included when adding folders to the zip
+ */
public boolean isReadHiddenFiles() {
return readHiddenFiles;
}
-
+
+ /**
+ * Indicate if hidden files will be included during folder recursion
+ *
+ * @param readHiddenFiles if true, hidden files will be included when adding folders to the zip
+ */
public void setReadHiddenFiles(boolean readHiddenFiles) {
this.readHiddenFiles = readHiddenFiles;
}
-
+
+ /**
+ * Test if hidden folders will be included during folder recursion
+ *
+ * @return true if hidden folders will be included when adding folders to the zip
+ */
public boolean isReadHiddenFolders() {
return readHiddenFolders;
}
-
+
+ /**
+ * Indicate if hidden folders will be included during folder recursion
+ * @param readHiddenFolders if true, hidden folders will be included when added folders to the zip
+ */
public void setReadHiddenFolders(boolean readHiddenFolders) {
this.readHiddenFolders = readHiddenFolders;
}
@@ -123,26 +206,50 @@ public class ZipParameters {
return super.clone();
}
+ /**
+ * Get the key strength of the AES encryption key
+ * @return the key strength of the AES encryption key
+ */
public AesKeyStrength getAesKeyStrength() {
return aesKeyStrength;
}
+ /**
+ * Set the key strength of the AES encryption key
+ * @param aesKeyStrength the key strength of the AES encryption key
+ */
public void setAesKeyStrength(AesKeyStrength aesKeyStrength) {
this.aesKeyStrength = aesKeyStrength;
}
+ /**
+ * Get the AES format version used for encryption
+ * @return the AES format version used for encryption
+ */
public AesVersion getAesVersion() {
return aesVersion;
}
+ /**
+ * Set the AES format version to use for encryption
+ * @param aesVersion the AES format version to use
+ */
public void setAesVersion(AesVersion aesVersion) {
this.aesVersion = aesVersion;
}
+ /**
+ * Test if the parent folder of the added files will be included in the ZIP
+ * @return true if the parent folder of the added files will be included into the zip
+ */
public boolean isIncludeRootFolder() {
return includeRootFolder;
}
+ /**
+ * Set the flag to indicate if the parent folder of added files will be included in the ZIP
+ * @param includeRootFolder if true, the parent folder of added files will be included in the ZIP
+ */
public void setIncludeRootFolder(boolean includeRootFolder) {
this.includeRootFolder = includeRootFolder;
}
@@ -167,14 +274,32 @@ public class ZipParameters {
return fileNameInZip;
}
- public void setFileNameInZip(String fileNameInZip) {
+ /**
+ * Set the filename that will be used to include a file into the ZIP file to a different name
+ * that given by the source filename added to the ZIP file. The filenameInZip must
+ * adhere to the ZIP filename specification, including the use of forward slash '/' as the
+ * directory separator, and it must also be a relative file. If the filenameInZip given is not null and
+ * not empty, the value specified by setRootFolderNameInZip() will be ignored.
+ *
+ * @param fileNameInZip the filename to set in the ZIP. Use null or an empty String to set the default behavior
+ */
+ public void setFileNameInZip(String fileNameInZip) {
this.fileNameInZip = fileNameInZip;
}
+ /**
+ * Get the last modified time to be used for files written to the ZIP
+ * @return the last modified time in milliseconds since the epoch
+ */
public long getLastModifiedFileTime() {
return lastModifiedFileTime;
}
+ /**
+ * Set the last modified time recorded in the ZIP file for the added files. If less than 0,
+ * the last modified time is cleared and the current time is used
+ * @param lastModifiedFileTime the last modified time in milliseconds since the epoch
+ */
public void setLastModifiedFileTime(long lastModifiedFileTime) {
if (lastModifiedFileTime <= 0) {
return;
@@ -203,6 +328,10 @@ public class ZipParameters {
return overrideExistingFilesInZip;
}
+ /**
+ * Set the behavior if a file is added that already exists in the ZIP.
+ * @param overrideExistingFilesInZip if true, remove the existing file in the ZIP; if false do not add the new file
+ */
public void setOverrideExistingFilesInZip(boolean overrideExistingFilesInZip) {
this.overrideExistingFilesInZip = overrideExistingFilesInZip;
}
@@ -211,23 +340,78 @@ public class ZipParameters {
return rootFolderNameInZip;
}
+ /**
+ * Set the folder name that will be prepended to the filename in the ZIP. This value is ignored
+ * if setFileNameInZip() is specified with a non-null, non-empty string.
+ *
+ * @param rootFolderNameInZip the name of the folder to be prepended to the filename
+ * in the ZIP archive
+ */
public void setRootFolderNameInZip(String rootFolderNameInZip) {
this.rootFolderNameInZip = rootFolderNameInZip;
}
+ /**
+ * Get the file comment
+ * @return the file comment
+ */
public String getFileComment() {
return fileComment;
}
+ /**
+ * Set the file comment
+ * @param fileComment the file comment
+ */
public void setFileComment(String fileComment) {
this.fileComment = fileComment;
}
+ /**
+ * Get the behavior when adding a symbolic link
+ * @return the behavior when adding a symbolic link
+ */
public SymbolicLinkAction getSymbolicLinkAction() {
return symbolicLinkAction;
}
+ /**
+ * Set the behavior when adding a symbolic link
+ * @param symbolicLinkAction the behavior when adding a symbolic link
+ */
public void setSymbolicLinkAction(SymbolicLinkAction symbolicLinkAction) {
this.symbolicLinkAction = symbolicLinkAction;
}
+
+ /**
+ * Returns the file exclusion filter that is currently being used when adding files/folders to zip file
+ * @return ExcludeFileFilter
+ */
+ public ExcludeFileFilter getExcludeFileFilter() {
+ return excludeFileFilter;
+ }
+
+ /**
+ * Set a filter to exclude any files from the list of files being added to zip. Mostly used when adding a folder
+ * to a zip, and if certain files have to be excluded from adding to the zip file.
+ */
+ public void setExcludeFileFilter(ExcludeFileFilter excludeFileFilter) {
+ this.excludeFileFilter = excludeFileFilter;
+ }
+
+ /**
+ * Returns true if zip4j is using unix mode as default. Returns False otherwise.
+ * @return true if zip4j is using unix mode as default, false otherwise
+ */
+ public boolean isUnixMode() {
+ return unixMode;
+ }
+
+ /**
+ * When set to true, zip4j uses unix mode as default when generating file headers.
+ * @param unixMode
+ */
+ public void setUnixMode(boolean unixMode) {
+ this.unixMode = unixMode;
+ }
}
=====================================
src/main/java/net/lingala/zip4j/model/enums/AesKeyStrength.java
=====================================
@@ -1,9 +1,22 @@
package net.lingala.zip4j.model.enums;
+/**
+ * Indicates the AES encryption key length
+ *
+ */
public enum AesKeyStrength {
+ /**
+ * 128-bit AES key length
+ */
KEY_STRENGTH_128(1, 8, 16, 16),
+ /**
+ * 192-bit AES key length
+ */
KEY_STRENGTH_192(2, 12, 24, 24),
+ /**
+ * 256-bit AES key length
+ */
KEY_STRENGTH_256(3, 16, 32, 32);
private int rawCode;
@@ -18,7 +31,11 @@ public enum AesKeyStrength {
this.keyLength = keyLength;
}
- public int getRawCode() {
+ /**
+ * Get the code written to the ZIP file
+ * @return the code written the ZIP file
+ */
+ public int getRawCode() {
return rawCode;
}
@@ -29,11 +46,19 @@ public enum AesKeyStrength {
public int getMacLength() {
return macLength;
}
-
+ /**
+ * Get the key length in bytes that this AesKeyStrength represents
+ * @return the key length in bytes
+ */
public int getKeyLength() {
return keyLength;
}
+ /**
+ * Get a AesKeyStrength given a code from the ZIP file
+ * @param code the code from the ZIP file
+ * @return the AesKeyStrength that represents the given code, or null if the code does not match
+ */
public static AesKeyStrength getAesKeyStrengthFromRawCode(int code) {
for (AesKeyStrength aesKeyStrength : values()) {
if (aesKeyStrength.getRawCode() == code) {
=====================================
src/main/java/net/lingala/zip4j/model/enums/AesVersion.java
=====================================
@@ -1,8 +1,17 @@
package net.lingala.zip4j.model.enums;
+/**
+ * Indicates the AES format used
+ */
public enum AesVersion {
+ /**
+ * Version 1 of the AES format
+ */
ONE(1),
+ /**
+ * Version 2 of the AES format
+ */
TWO(2);
private int versionNumber;
@@ -11,10 +20,18 @@ public enum AesVersion {
this.versionNumber = versionNumber;
}
+ /**
+ * Get the AES version number as an integer
+ * @return the AES version number
+ */
public int getVersionNumber() {
return versionNumber;
}
-
+ /**
+ * Get the AESVersion instance from an integer AES version number
+ * @return the AESVersion instance for a given version
+ * @throws IllegalArgumentException if an unsupported version is given
+ */
public static AesVersion getFromVersionNumber(int versionNumber) {
for (AesVersion aesVersion : values()) {
if (aesVersion.versionNumber == versionNumber) {
=====================================
src/main/java/net/lingala/zip4j/model/enums/CompressionLevel.java
=====================================
@@ -1,11 +1,35 @@
package net.lingala.zip4j.model.enums;
+/**
+ * Indicates the level of compression for the DEFLATE compression method
+ *
+ */
public enum CompressionLevel {
+ /**
+ * Level 1 Deflate compression
+ * @see java.util.zip.Deflater#BEST_SPEED
+ */
FASTEST(1),
+ /**
+ * Level 3 Deflate compression
+ * @see java.util.zip.Deflater
+ */
FAST(3),
+ /**
+ * Level 5 Deflate compression
+ * @see java.util.zip.Deflater
+ */
NORMAL(5),
+ /**
+ * Level 7 Deflate compression
+ * @see java.util.zip.Deflater
+ */
MAXIMUM(7),
+ /**
+ * Level 9 Deflate compression. Not part of the original ZIP format specification.
+ * @see java.util.zip.Deflater#BEST_COMPRESSION
+ */
ULTRA(9);
private int level;
@@ -14,6 +38,10 @@ public enum CompressionLevel {
this.level = level;
}
+ /**
+ * Get the Deflate compression level (0-9) for this CompressionLevel
+ * @return the deflate compression level
+ */
public int getLevel() {
return level;
}
=====================================
src/main/java/net/lingala/zip4j/model/enums/CompressionMethod.java
=====================================
@@ -2,10 +2,24 @@ package net.lingala.zip4j.model.enums;
import net.lingala.zip4j.exception.ZipException;
+/**
+ * Indicates the algorithm used for compression
+ *
+ */
public enum CompressionMethod {
+ /**
+ * No compression is performed
+ */
STORE(0),
+ /**
+ * The Deflate compression is used.
+ * @see java.util.zip.Deflater
+ */
DEFLATE(8),
+ /**
+ * For internal use in Zip4J
+ */
AES_INTERNAL_ONLY(99);
private int code;
@@ -14,10 +28,20 @@ public enum CompressionMethod {
this.code = code;
}
+ /**
+ * Get the code used in the ZIP file for this CompressionMethod
+ * @return the code used in the ZIP file
+ */
public int getCode() {
return code;
}
+ /**
+ * Get the CompressionMethod for a given ZIP file code
+ * @param code the code for a compression method
+ * @return the CompressionMethod related to the given code
+ * @throws ZipException on unknown code
+ */
public static CompressionMethod getCompressionMethodFromCode(int code) throws ZipException {
for (CompressionMethod compressionMethod : values()) {
if (compressionMethod.getCode() == code) {
=====================================
src/main/java/net/lingala/zip4j/model/enums/EncryptionMethod.java
=====================================
@@ -1,10 +1,27 @@
package net.lingala.zip4j.model.enums;
+/**
+ * Indicates the encryption method used in the ZIP file
+ *
+ */
public enum EncryptionMethod {
+ /**
+ * No encryption is performed
+ */
NONE,
+ /**
+ * Encrypted with the weak ZIP standard algorithm
+ */
ZIP_STANDARD,
+ /**
+ * Encrypted with the stronger ZIP standard algorithm
+ */
ZIP_STANDARD_VARIANT_STRONG,
+ /**
+ * Encrypted with AES, the strongest choice but currently
+ * cannot be expanded in Windows Explorer
+ */
AES
}
=====================================
src/main/java/net/lingala/zip4j/tasks/AddFolderToZipTask.java
=====================================
@@ -32,7 +32,8 @@ public class AddFolderToZipTask extends AbstractAddFileToZipTask<AddFolderToZipT
protected long calculateTotalWork(AddFolderToZipTaskParameters taskParameters) throws ZipException {
List<File> filesToAdd = getFilesInDirectoryRecursive(taskParameters.folderToAdd,
taskParameters.zipParameters.isReadHiddenFiles(),
- taskParameters.zipParameters.isReadHiddenFolders());
+ taskParameters.zipParameters.isReadHiddenFolders(),
+ taskParameters.zipParameters.getExcludeFileFilter());
if (taskParameters.zipParameters.isIncludeRootFolder()) {
filesToAdd.add(taskParameters.folderToAdd);
@@ -61,7 +62,8 @@ public class AddFolderToZipTask extends AbstractAddFileToZipTask<AddFolderToZipT
private List<File> getFilesToAdd(AddFolderToZipTaskParameters taskParameters) throws ZipException {
List<File> filesToAdd = getFilesInDirectoryRecursive(taskParameters.folderToAdd,
taskParameters.zipParameters.isReadHiddenFiles(),
- taskParameters.zipParameters.isReadHiddenFolders());
+ taskParameters.zipParameters.isReadHiddenFolders(),
+ taskParameters.zipParameters.getExcludeFileFilter());
if (taskParameters.zipParameters.isIncludeRootFolder()) {
filesToAdd.add(taskParameters.folderToAdd);
=====================================
src/main/java/net/lingala/zip4j/tasks/ExtractAllFilesTask.java
=====================================
@@ -11,6 +11,8 @@ import net.lingala.zip4j.util.UnzipUtil;
import java.io.IOException;
import java.nio.charset.Charset;
+import static net.lingala.zip4j.headers.HeaderUtil.getTotalUncompressedSizeOfAllFileHeaders;
+
public class ExtractAllFilesTask extends AbstractExtractFileTask<ExtractAllFilesTaskParameters> {
private char[] password;
@@ -45,18 +47,7 @@ public class ExtractAllFilesTask extends AbstractExtractFileTask<ExtractAllFiles
@Override
protected long calculateTotalWork(ExtractAllFilesTaskParameters taskParameters) {
- long totalWork = 0;
-
- for (FileHeader fileHeader : getZipModel().getCentralDirectory().getFileHeaders()) {
- if (fileHeader.getZip64ExtendedInfo() != null &&
- fileHeader.getZip64ExtendedInfo().getUncompressedSize() > 0) {
- totalWork += fileHeader.getZip64ExtendedInfo().getUncompressedSize();
- } else {
- totalWork += fileHeader.getUncompressedSize();
- }
- }
-
- return totalWork;
+ return getTotalUncompressedSizeOfAllFileHeaders(getZipModel().getCentralDirectory().getFileHeaders());
}
private ZipInputStream prepareZipInputStream(Charset charset) throws IOException {
=====================================
src/main/java/net/lingala/zip4j/tasks/ExtractFileTask.java
=====================================
@@ -6,10 +6,17 @@ import net.lingala.zip4j.model.FileHeader;
import net.lingala.zip4j.model.ZipModel;
import net.lingala.zip4j.progress.ProgressMonitor;
import net.lingala.zip4j.tasks.ExtractFileTask.ExtractFileTaskParameters;
+import net.lingala.zip4j.util.InternalZipConstants;
import net.lingala.zip4j.util.UnzipUtil;
+import net.lingala.zip4j.util.Zip4jUtil;
import java.io.IOException;
import java.nio.charset.Charset;
+import java.util.Collections;
+import java.util.List;
+
+import static net.lingala.zip4j.headers.HeaderUtil.getFileHeadersUnderDirectory;
+import static net.lingala.zip4j.headers.HeaderUtil.getTotalUncompressedSizeOfAllFileHeaders;
public class ExtractFileTask extends AbstractExtractFileTask<ExtractFileTaskParameters> {
@@ -24,9 +31,13 @@ public class ExtractFileTask extends AbstractExtractFileTask<ExtractFileTaskPara
@Override
protected void executeTask(ExtractFileTaskParameters taskParameters, ProgressMonitor progressMonitor)
throws IOException {
+
try(ZipInputStream zipInputStream = createZipInputStream(taskParameters.fileHeader, taskParameters.charset)) {
- extractFile(zipInputStream, taskParameters.fileHeader, taskParameters.outputPath, taskParameters.newFileName,
- progressMonitor);
+ List<FileHeader> fileHeadersUnderDirectory = getFileHeadersToExtract(taskParameters.fileHeader);
+ for (FileHeader fileHeader : fileHeadersUnderDirectory) {
+ String newFileName = determineNewFileName(taskParameters.newFileName, taskParameters.fileHeader, fileHeader);
+ extractFile(zipInputStream, fileHeader, taskParameters.outputPath, newFileName, progressMonitor);
+ }
} finally {
if (splitInputStream != null) {
splitInputStream.close();
@@ -36,15 +47,43 @@ public class ExtractFileTask extends AbstractExtractFileTask<ExtractFileTaskPara
@Override
protected long calculateTotalWork(ExtractFileTaskParameters taskParameters) {
- return taskParameters.fileHeader.getUncompressedSize();
+ List<FileHeader> fileHeadersUnderDirectory = getFileHeadersToExtract(taskParameters.fileHeader);
+ return getTotalUncompressedSizeOfAllFileHeaders(fileHeadersUnderDirectory);
+ }
+
+ private List<FileHeader> getFileHeadersToExtract(FileHeader rootFileHeader) {
+ if (!rootFileHeader.isDirectory()) {
+ return Collections.singletonList(rootFileHeader);
+ }
+
+ return getFileHeadersUnderDirectory(
+ getZipModel().getCentralDirectory().getFileHeaders(), rootFileHeader);
}
- protected ZipInputStream createZipInputStream(FileHeader fileHeader, Charset charset) throws IOException {
+ private ZipInputStream createZipInputStream(FileHeader fileHeader, Charset charset) throws IOException {
splitInputStream = UnzipUtil.createSplitInputStream(getZipModel());
splitInputStream.prepareExtractionForFileHeader(fileHeader);
return new ZipInputStream(splitInputStream, password, charset);
}
+ private String determineNewFileName(String newFileName, FileHeader fileHeaderToExtract, FileHeader fileHeaderBeingExtracted) {
+ if (!Zip4jUtil.isStringNotNullAndNotEmpty(newFileName)) {
+ return newFileName;
+ }
+
+ if (!fileHeaderToExtract.isDirectory()) {
+ return newFileName;
+ }
+
+ String fileSeparator = InternalZipConstants.ZIP_FILE_SEPARATOR;
+ if (newFileName.endsWith(InternalZipConstants.ZIP_FILE_SEPARATOR)) {
+ fileSeparator = "";
+ }
+
+ return fileHeaderBeingExtracted.getFileName().replaceFirst(fileHeaderToExtract.getFileName(),
+ newFileName + fileSeparator);
+ }
+
public static class ExtractFileTaskParameters extends AbstractZipTaskParameters {
private String outputPath;
private FileHeader fileHeader;
=====================================
src/main/java/net/lingala/zip4j/util/FileUtils.java
=====================================
@@ -1,6 +1,7 @@
package net.lingala.zip4j.util;
import net.lingala.zip4j.exception.ZipException;
+import net.lingala.zip4j.model.ExcludeFileFilter;
import net.lingala.zip4j.model.ZipModel;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.progress.ProgressMonitor;
@@ -89,7 +90,11 @@ public class FileUtils {
}
}
- public static List<File> getFilesInDirectoryRecursive(File path, boolean readHiddenFiles, boolean readHiddenFolders)
+ public static List<File> getFilesInDirectoryRecursive(File path, boolean readHiddenFiles, boolean readHiddenFolders) throws ZipException {
+ return getFilesInDirectoryRecursive(path, readHiddenFiles, readHiddenFolders, null);
+ }
+
+ public static List<File> getFilesInDirectoryRecursive(File path, boolean readHiddenFiles, boolean readHiddenFolders, ExcludeFileFilter excludedFiles)
throws ZipException {
if (path == null) {
@@ -104,6 +109,10 @@ public class FileUtils {
}
for (File file : filesAndDirs) {
+ if (excludedFiles != null && excludedFiles.isExcluded(file)) {
+ continue;
+ }
+
if (file.isHidden()) {
if (file.isDirectory()) {
if (!readHiddenFolders) {
@@ -115,7 +124,7 @@ public class FileUtils {
}
result.add(file);
if (file.isDirectory()) {
- result.addAll(getFilesInDirectoryRecursive(file, readHiddenFiles, readHiddenFolders));
+ result.addAll(getFilesInDirectoryRecursive(file, readHiddenFiles, readHiddenFolders, excludedFiles));
}
}
@@ -483,6 +492,11 @@ public class FileUtils {
}
}
+ public static boolean isWindows() {
+ String os = System.getProperty("os.name").toLowerCase();
+ return isWindows(os);
+ }
+
private static boolean isWindows(String os) {
return (os.contains("win"));
}
=====================================
src/main/java/net/lingala/zip4j/util/ZipVersionUtils.java
=====================================
@@ -0,0 +1,39 @@
+package net.lingala.zip4j.util;
+
+import net.lingala.zip4j.headers.VersionMadeBy;
+import net.lingala.zip4j.headers.VersionNeededToExtract;
+import net.lingala.zip4j.model.ZipParameters;
+import net.lingala.zip4j.model.enums.CompressionMethod;
+import net.lingala.zip4j.model.enums.EncryptionMethod;
+
+public class ZipVersionUtils {
+
+ public static int determineVersionMadeBy(ZipParameters zipParameters, RawIO rawIO) {
+ byte[] versionMadeBy = new byte[2];
+ versionMadeBy[0] = VersionMadeBy.SPECIFICATION_VERSION.getCode();
+ versionMadeBy[1] = VersionMadeBy.UNIX.getCode();
+ if (FileUtils.isWindows() && !zipParameters.isUnixMode()) { // skip setting windows mode if unix mode is forced
+ versionMadeBy[1] = VersionMadeBy.WINDOWS.getCode();
+ }
+
+ return rawIO.readShortLittleEndian(versionMadeBy, 0);
+ }
+
+ public static VersionNeededToExtract determineVersionNeededToExtract(ZipParameters zipParameters) {
+ VersionNeededToExtract versionRequired = VersionNeededToExtract.DEFAULT;
+
+ if (zipParameters.getCompressionMethod() == CompressionMethod.DEFLATE) {
+ versionRequired = VersionNeededToExtract.DEFLATE_COMPRESSED;
+ }
+
+ if (zipParameters.getEntrySize() > InternalZipConstants.ZIP_64_SIZE_LIMIT) {
+ versionRequired = VersionNeededToExtract.ZIP_64_FORMAT;
+ }
+
+ if (zipParameters.isEncryptFiles() && zipParameters.getEncryptionMethod().equals(EncryptionMethod.AES)) {
+ versionRequired = VersionNeededToExtract.AES_ENCRYPTED;
+ }
+
+ return versionRequired;
+ }
+}
=====================================
src/test/java/net/lingala/zip4j/AddFilesToZipIT.java
=====================================
@@ -16,6 +16,8 @@ import net.lingala.zip4j.testutils.TestUtils;
import net.lingala.zip4j.testutils.ZipFileVerifier;
import net.lingala.zip4j.util.BitUtils;
import net.lingala.zip4j.util.InternalZipConstants;
+import net.lingala.zip4j.util.RawIO;
+import net.lingala.zip4j.util.ZipVersionUtils;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
@@ -25,6 +27,7 @@ import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
@@ -36,6 +39,8 @@ import static org.assertj.core.api.Assertions.assertThat;
public class AddFilesToZipIT extends AbstractIT {
+ private RawIO rawIO = new RawIO();
+
@Rule
public ExpectedException expectedException = ExpectedException.none();
@@ -55,6 +60,7 @@ public class AddFilesToZipIT extends AbstractIT {
ZipFileVerifier.verifyZipFileByExtractingAllFiles(generatedZipFile, outputFolder, 1);
verifyZipFileContainsFiles(generatedZipFile, singletonList("sample.pdf"), CompressionMethod.DEFLATE, null, null);
+ verifyZipVersions(zipFile.getFileHeaders().get(0), new ZipParameters());
}
@Test
@@ -82,6 +88,7 @@ public class AddFilesToZipIT extends AbstractIT {
ZipFileVerifier.verifyZipFileByExtractingAllFiles(generatedZipFile, PASSWORD, outputFolder, 1, true, CHARSET_CP_949);
assertThat(zipFile.getFileHeaders().get(0).getFileName()).isEqualTo(koreanFileName);
+ verifyZipVersions(zipFile.getFileHeaders().get(0), zipParameters);
}
@Test
@@ -138,6 +145,7 @@ public class AddFilesToZipIT extends AbstractIT {
ZipFileVerifier.verifyZipFileByExtractingAllFiles(generatedZipFile, PASSWORD, outputFolder, 1);
verifyZipFileContainsFiles(generatedZipFile, singletonList("sample_text_large.txt"), CompressionMethod.STORE,
EncryptionMethod.AES, AesKeyStrength.KEY_STRENGTH_128);
+ verifyZipVersions(zipFile.getFileHeaders().get(0), zipParameters);
}
@Test
@@ -620,6 +628,23 @@ public class AddFilesToZipIT extends AbstractIT {
ZipFileVerifier.verifyZipFileByExtractingAllFiles(generatedZipFile, outputFolder, 13);
}
+ @Test
+ public void testAddFolderWithExcludeFileFilter() throws IOException {
+ ZipFile zipFile = new ZipFile(generatedZipFile);
+ List<File> filesToExclude = Arrays.asList(
+ TestUtils.getTestFileFromResources("sample.pdf"),
+ TestUtils.getTestFileFromResources("sample_directory/favicon.ico")
+ );
+ ZipParameters zipParameters = new ZipParameters();
+ zipParameters.setIncludeRootFolder(false);
+ zipParameters.setExcludeFileFilter(filesToExclude::contains);
+
+ zipFile.addFolder(TestUtils.getTestFileFromResources(""), zipParameters);
+
+ ZipFileVerifier.verifyZipFileByExtractingAllFiles(generatedZipFile, outputFolder, 10);
+ verifyZipFileDoesNotContainFiles(generatedZipFile, Arrays.asList("sample.pdf", "sample_directory/favicon.ico"));
+ }
+
@Test
public void testAddStreamToZipThrowsExceptionWhenFileNameIsNull() throws IOException {
ZipFile zipFile = new ZipFile(generatedZipFile);
@@ -849,6 +874,17 @@ public class AddFilesToZipIT extends AbstractIT {
verifyAllFilesAreOf(fileHeaders, compressionMethod, encryptionMethod, aesKeyStrength, aesVersion);
}
+ private void verifyZipFileDoesNotContainFiles(File generatedZipFile, List<String> fileNamesNotInZip) throws ZipException {
+ ZipFile zipFile = new ZipFile(generatedZipFile);
+ for (FileHeader fileHeader : zipFile.getFileHeaders()) {
+ for (String fileNameNotInZip : fileNamesNotInZip) {
+ assertThat(fileHeader.getFileName())
+ .withFailMessage("Expected file " + fileNameNotInZip + " to not be present in zip file")
+ .isNotEqualTo(fileNameNotInZip);
+ }
+ }
+ }
+
private void verifyFoldersInZip(List<FileHeader> fileHeaders, File generatedZipFile, char[] password)
throws IOException {
verifyFoldersInFileHeaders(fileHeaders);
@@ -973,4 +1009,12 @@ public class AddFilesToZipIT extends AbstractIT {
return compressionMethod;
}
+
+ private void verifyZipVersions(FileHeader fileHeader, ZipParameters zipParameters) {
+ int versionMadeBy = ZipVersionUtils.determineVersionMadeBy(zipParameters, rawIO);
+ int versionNeededToExtract = ZipVersionUtils.determineVersionNeededToExtract(zipParameters).getCode();
+
+ assertThat(fileHeader.getVersionMadeBy()).isEqualTo(versionMadeBy);
+ assertThat(fileHeader.getVersionNeededToExtract()).isEqualTo(versionNeededToExtract);
+ }
}
=====================================
src/test/java/net/lingala/zip4j/ExtractZipFileIT.java
=====================================
@@ -18,6 +18,7 @@ import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
+import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
@@ -448,6 +449,32 @@ public class ExtractZipFileIT extends AbstractIT {
assertThat(zipFile.getFileHeaders()).hasSize(19);
}
+ @Test
+ public void testExtractFileHeaderExtractAllFilesIfFileHeaderIsDirectory() throws IOException {
+ ZipFile zipFile = new ZipFile(generatedZipFile);
+ ZipParameters zipParameters = new ZipParameters();
+ zipParameters.setIncludeRootFolder(false);
+ zipFile.addFolder(TestUtils.getTestFileFromResources(""), zipParameters);
+
+ zipFile.extractFile(zipFile.getFileHeader("öüäöäö/"), outputFolder.getPath());
+ File outputFile = Paths.get(outputFolder.getPath(), "öüäöäö", "asöäööl").toFile();
+ assertThat(outputFile).exists();
+ ZipFileVerifier.verifyFileContent(TestUtils.getTestFileFromResources("öüäöäö/asöäööl"), outputFile);
+ }
+
+ @Test
+ public void testExtractFileHeaderExtractAllFilesIfFileHeaderIsDirectoryAndRenameFile() throws IOException {
+ ZipFile zipFile = new ZipFile(generatedZipFile);
+ ZipParameters zipParameters = new ZipParameters();
+ zipParameters.setIncludeRootFolder(false);
+ zipFile.addFolder(TestUtils.getTestFileFromResources(""), zipParameters);
+
+ zipFile.extractFile(zipFile.getFileHeader("öüäöäö/"), outputFolder.getPath(), "new_folder_name/");
+ File outputFile = Paths.get(outputFolder.getPath(), "new_folder_name", "asöäööl").toFile();
+ assertThat(outputFile).exists();
+ ZipFileVerifier.verifyFileContent(TestUtils.getTestFileFromResources("öüäöäö/asöäööl"), outputFile);
+ }
+
private void addFileToZip(ZipFile zipFile, String fileName, EncryptionMethod encryptionMethod, String password) throws ZipException {
ZipParameters zipParameters = new ZipParameters();
zipParameters.setEncryptFiles(encryptionMethod != null);
=====================================
src/test/java/net/lingala/zip4j/headers/FileHeaderFactoryTest.java
=====================================
@@ -11,6 +11,9 @@ import net.lingala.zip4j.model.enums.CompressionLevel;
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.RawIO;
+import org.junit.After;
+import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
@@ -23,25 +26,37 @@ import static org.assertj.core.api.Assertions.assertThat;
public class FileHeaderFactoryTest {
+ private static final String ACTUAL_OS = System.getProperty("os.name");
private static final String FILE_NAME_IN_ZIP = "filename.txt";
private static final long ENTRY_CRC = 2323L;
private FileHeaderFactory fileHeaderFactory = new FileHeaderFactory();
+ private RawIO rawIO = new RawIO();
@Rule
public ExpectedException expectedException = ExpectedException.none();
+ @Before
+ public void setup() {
+ System.setProperty("os.name", "linux");
+ }
+
+ @After
+ public void cleanup() {
+ System.setProperty("os.name", ACTUAL_OS);
+ }
+
@Test
public void testGenerateFileHeaderWithoutFileNameThrowsException() throws ZipException {
expectedException.expect(ZipException.class);
expectedException.expectMessage("fileNameInZip is null or empty");
- fileHeaderFactory.generateFileHeader(new ZipParameters(), false, 0, InternalZipConstants.CHARSET_UTF_8);
+ fileHeaderFactory.generateFileHeader(new ZipParameters(), false, 0, InternalZipConstants.CHARSET_UTF_8, rawIO);
}
@Test
public void testGenerateFileHeaderDefaults() throws ZipException {
- FileHeader fileHeader = fileHeaderFactory.generateFileHeader(generateZipParameters(), false, 0, InternalZipConstants.CHARSET_UTF_8);
+ FileHeader fileHeader = fileHeaderFactory.generateFileHeader(generateZipParameters(), false, 0, InternalZipConstants.CHARSET_UTF_8, rawIO);
assertThat(fileHeader).isNotNull();
assertThat(fileHeader.getCompressionMethod()).isEqualTo(CompressionMethod.DEFLATE);
@@ -60,8 +75,8 @@ public class FileHeaderFactoryTest {
ZipParameters zipParameters = generateZipParameters();
zipParameters.setCompressionMethod(CompressionMethod.STORE);
- FileHeader fileHeader = fileHeaderFactory.generateFileHeader(zipParameters, false, 0, InternalZipConstants.CHARSET_UTF_8);
- verifyFileHeader(fileHeader, zipParameters, false, 0, false);
+ FileHeader fileHeader = fileHeaderFactory.generateFileHeader(zipParameters, false, 0, InternalZipConstants.CHARSET_UTF_8, rawIO);
+ verifyFileHeader(fileHeader, zipParameters, false, 0, 10, false);
}
@Test
@@ -72,7 +87,7 @@ public class FileHeaderFactoryTest {
ZipParameters zipParameters = generateZipParameters();
zipParameters.setEncryptFiles(true);
- fileHeaderFactory.generateFileHeader(zipParameters, false, 0, InternalZipConstants.CHARSET_UTF_8);
+ fileHeaderFactory.generateFileHeader(zipParameters, false, 0, InternalZipConstants.CHARSET_UTF_8, rawIO);
}
@Test
@@ -81,8 +96,8 @@ public class FileHeaderFactoryTest {
zipParameters.setEncryptFiles(true);
zipParameters.setEncryptionMethod(EncryptionMethod.ZIP_STANDARD);
- FileHeader fileHeader = fileHeaderFactory.generateFileHeader(zipParameters, false, 0, InternalZipConstants.CHARSET_UTF_8);
- verifyFileHeader(fileHeader, zipParameters, false, 0, false);
+ FileHeader fileHeader = fileHeaderFactory.generateFileHeader(zipParameters, false, 0, InternalZipConstants.CHARSET_UTF_8, rawIO);
+ verifyFileHeader(fileHeader, zipParameters, false, 0, 20, false);
}
@Test
@@ -95,7 +110,7 @@ public class FileHeaderFactoryTest {
zipParameters.setEncryptionMethod(EncryptionMethod.AES);
zipParameters.setAesKeyStrength(null);
- fileHeaderFactory.generateFileHeader(zipParameters, false, 0, InternalZipConstants.CHARSET_UTF_8);
+ fileHeaderFactory.generateFileHeader(zipParameters, false, 0, InternalZipConstants.CHARSET_UTF_8, rawIO);
}
@Test
@@ -104,8 +119,8 @@ public class FileHeaderFactoryTest {
zipParameters.setEncryptFiles(true);
zipParameters.setEncryptionMethod(EncryptionMethod.AES);
- FileHeader fileHeader = fileHeaderFactory.generateFileHeader(zipParameters, false, 0, InternalZipConstants.CHARSET_UTF_8);
- verifyFileHeader(fileHeader, zipParameters, false, 0, true);
+ FileHeader fileHeader = fileHeaderFactory.generateFileHeader(zipParameters, false, 0, InternalZipConstants.CHARSET_UTF_8, rawIO);
+ verifyFileHeader(fileHeader, zipParameters, false, 0, 51, true);
verifyAesExtraDataRecord(fileHeader.getAesExtraDataRecord(), AesKeyStrength.KEY_STRENGTH_256,
CompressionMethod.DEFLATE, AesVersion.TWO);
}
@@ -117,8 +132,8 @@ public class FileHeaderFactoryTest {
zipParameters.setEncryptionMethod(EncryptionMethod.AES);
zipParameters.setAesKeyStrength(AesKeyStrength.KEY_STRENGTH_128);
- FileHeader fileHeader = fileHeaderFactory.generateFileHeader(zipParameters, false, 0, InternalZipConstants.CHARSET_UTF_8);
- verifyFileHeader(fileHeader, zipParameters, false, 0, true);
+ FileHeader fileHeader = fileHeaderFactory.generateFileHeader(zipParameters, false, 0, InternalZipConstants.CHARSET_UTF_8, rawIO);
+ verifyFileHeader(fileHeader, zipParameters, false, 0, 51, true);
verifyAesExtraDataRecord(fileHeader.getAesExtraDataRecord(), AesKeyStrength.KEY_STRENGTH_128,
CompressionMethod.DEFLATE, AesVersion.TWO);
}
@@ -130,8 +145,8 @@ public class FileHeaderFactoryTest {
zipParameters.setEncryptionMethod(EncryptionMethod.AES);
zipParameters.setAesKeyStrength(AesKeyStrength.KEY_STRENGTH_192);
- FileHeader fileHeader = fileHeaderFactory.generateFileHeader(zipParameters, false, 0, InternalZipConstants.CHARSET_UTF_8);
- verifyFileHeader(fileHeader, zipParameters, false, 0, true);
+ FileHeader fileHeader = fileHeaderFactory.generateFileHeader(zipParameters, false, 0, InternalZipConstants.CHARSET_UTF_8, rawIO);
+ verifyFileHeader(fileHeader, zipParameters, false, 0, 51, true);
verifyAesExtraDataRecord(fileHeader.getAesExtraDataRecord(), AesKeyStrength.KEY_STRENGTH_192,
CompressionMethod.DEFLATE, AesVersion.TWO);
}
@@ -143,8 +158,8 @@ public class FileHeaderFactoryTest {
zipParameters.setEncryptionMethod(EncryptionMethod.AES);
zipParameters.setAesKeyStrength(AesKeyStrength.KEY_STRENGTH_256);
- FileHeader fileHeader = fileHeaderFactory.generateFileHeader(zipParameters, false, 0, InternalZipConstants.CHARSET_UTF_8);
- verifyFileHeader(fileHeader, zipParameters, false, 0, true);
+ FileHeader fileHeader = fileHeaderFactory.generateFileHeader(zipParameters, false, 0, InternalZipConstants.CHARSET_UTF_8, rawIO);
+ verifyFileHeader(fileHeader, zipParameters, false, 0, 51, true);
verifyAesExtraDataRecord(fileHeader.getAesExtraDataRecord(), AesKeyStrength.KEY_STRENGTH_256,
CompressionMethod.DEFLATE, AesVersion.TWO);
}
@@ -157,8 +172,8 @@ public class FileHeaderFactoryTest {
zipParameters.setAesKeyStrength(AesKeyStrength.KEY_STRENGTH_256);
zipParameters.setAesVersion(AesVersion.ONE);
- FileHeader fileHeader = fileHeaderFactory.generateFileHeader(zipParameters, false, 0, InternalZipConstants.CHARSET_UTF_8);
- verifyFileHeader(fileHeader, zipParameters, false, 0, true);
+ FileHeader fileHeader = fileHeaderFactory.generateFileHeader(zipParameters, false, 0, InternalZipConstants.CHARSET_UTF_8, rawIO);
+ verifyFileHeader(fileHeader, zipParameters, false, 0, 51, true);
verifyAesExtraDataRecord(fileHeader.getAesExtraDataRecord(), AesKeyStrength.KEY_STRENGTH_256,
CompressionMethod.DEFLATE, AesVersion.ONE);
}
@@ -171,8 +186,8 @@ public class FileHeaderFactoryTest {
zipParameters.setAesKeyStrength(AesKeyStrength.KEY_STRENGTH_256);
zipParameters.setAesVersion(null);
- FileHeader fileHeader = fileHeaderFactory.generateFileHeader(zipParameters, false, 0, InternalZipConstants.CHARSET_UTF_8);
- verifyFileHeader(fileHeader, zipParameters, false, 0, true);
+ FileHeader fileHeader = fileHeaderFactory.generateFileHeader(zipParameters, false, 0, InternalZipConstants.CHARSET_UTF_8, rawIO);
+ verifyFileHeader(fileHeader, zipParameters, false, 0, 51, true);
verifyAesExtraDataRecord(fileHeader.getAesExtraDataRecord(), AesKeyStrength.KEY_STRENGTH_256,
CompressionMethod.DEFLATE, AesVersion.TWO);
}
@@ -183,7 +198,7 @@ public class FileHeaderFactoryTest {
ZipParameters zipParameters = generateZipParameters();
zipParameters.setLastModifiedFileTime(lastModifiedFileTime);
- FileHeader fileHeader = fileHeaderFactory.generateFileHeader(zipParameters, false, 0, InternalZipConstants.CHARSET_UTF_8);
+ FileHeader fileHeader = fileHeaderFactory.generateFileHeader(zipParameters, false, 0, InternalZipConstants.CHARSET_UTF_8, rawIO);
assertThat(fileHeader.getLastModifiedTime()).isEqualTo(javaToDosTime(zipParameters.getLastModifiedFileTime()));
}
@@ -193,7 +208,7 @@ public class FileHeaderFactoryTest {
ZipParameters zipParameters = generateZipParameters();
zipParameters.setCompressionLevel(CompressionLevel.ULTRA);
- FileHeader fileHeader = fileHeaderFactory.generateFileHeader(zipParameters, false, 0, InternalZipConstants.CHARSET_UTF_8);
+ FileHeader fileHeader = fileHeaderFactory.generateFileHeader(zipParameters, false, 0, InternalZipConstants.CHARSET_UTF_8, rawIO);
verifyCompressionLevelGridForDeflate(CompressionLevel.ULTRA, fileHeader.getGeneralPurposeFlag()[0]);
}
@@ -203,7 +218,7 @@ public class FileHeaderFactoryTest {
ZipParameters zipParameters = generateZipParameters();
zipParameters.setCompressionLevel(CompressionLevel.MAXIMUM);
- FileHeader fileHeader = fileHeaderFactory.generateFileHeader(zipParameters, false, 0, InternalZipConstants.CHARSET_UTF_8);
+ FileHeader fileHeader = fileHeaderFactory.generateFileHeader(zipParameters, false, 0, InternalZipConstants.CHARSET_UTF_8, rawIO);
verifyCompressionLevelGridForDeflate(CompressionLevel.MAXIMUM, fileHeader.getGeneralPurposeFlag()[0]);
}
@@ -213,7 +228,7 @@ public class FileHeaderFactoryTest {
ZipParameters zipParameters = generateZipParameters();
zipParameters.setCompressionLevel(CompressionLevel.FAST);
- FileHeader fileHeader = fileHeaderFactory.generateFileHeader(zipParameters, false, 0, InternalZipConstants.CHARSET_UTF_8);
+ FileHeader fileHeader = fileHeaderFactory.generateFileHeader(zipParameters, false, 0, InternalZipConstants.CHARSET_UTF_8, rawIO);
verifyCompressionLevelGridForDeflate(CompressionLevel.FAST, fileHeader.getGeneralPurposeFlag()[0]);
}
@@ -223,20 +238,20 @@ public class FileHeaderFactoryTest {
ZipParameters zipParameters = generateZipParameters();
zipParameters.setCompressionLevel(CompressionLevel.FASTEST);
- FileHeader fileHeader = fileHeaderFactory.generateFileHeader(zipParameters, false, 0, InternalZipConstants.CHARSET_UTF_8);
+ FileHeader fileHeader = fileHeaderFactory.generateFileHeader(zipParameters, false, 0, InternalZipConstants.CHARSET_UTF_8, rawIO);
verifyCompressionLevelGridForDeflate(CompressionLevel.FASTEST, fileHeader.getGeneralPurposeFlag()[0]);
}
@Test
public void testGenerateFileHeaderWithCorrectCharset() throws ZipException {
- FileHeader fileHeader = fileHeaderFactory.generateFileHeader(generateZipParameters(), false, 0, Charset.forName("Cp949"));
+ FileHeader fileHeader = fileHeaderFactory.generateFileHeader(generateZipParameters(), false, 0, Charset.forName("Cp949"), rawIO);
assertThat(isBitSet(fileHeader.getGeneralPurposeFlag()[1], 3)).isFalse();
}
@Test
public void testGenerateFileHeaderWithUTF8Charset() throws ZipException {
- FileHeader fileHeader = fileHeaderFactory.generateFileHeader(generateZipParameters(), false, 0, InternalZipConstants.CHARSET_UTF_8);
+ FileHeader fileHeader = fileHeaderFactory.generateFileHeader(generateZipParameters(), false, 0, InternalZipConstants.CHARSET_UTF_8, rawIO);
assertThat(isBitSet(fileHeader.getGeneralPurposeFlag()[1], 3)).isTrue();
}
@@ -250,6 +265,41 @@ public class FileHeaderFactoryTest {
verifyLocalFileHeader(localFileHeader, lastModifiedFileTime);
}
+ @Test
+ public void testVersionMadeByWindowsWithUnixModeOff() throws ZipException {
+ changeOsSystemPropertyToWindows();
+ testVersionMadeBy(generateZipParameters(), 51);
+ }
+
+ @Test
+ public void testVersionMadeByWindowsWithUnixModeOn() throws ZipException {
+ changeOsSystemPropertyToWindows();
+ ZipParameters zipParameters = generateZipParameters();
+ zipParameters.setUnixMode(true);
+ testVersionMadeBy(zipParameters, 819);
+ }
+
+ @Test
+ public void testVersionMadeByUnix() throws ZipException {
+ changeOsSystemPropertyToUnix();
+ testVersionMadeBy(generateZipParameters(), 819);
+ }
+
+ @Test
+ public void testVersionMadeByMac() throws ZipException {
+ changeOsSystemPropertyToMac();
+ testVersionMadeBy(generateZipParameters(), 819);
+ }
+
+ private void testVersionMadeBy(ZipParameters zipParameters, int expectedVersionMadeBy) {
+ try {
+ FileHeader fileHeader = fileHeaderFactory.generateFileHeader(zipParameters, false, 0, InternalZipConstants.CHARSET_UTF_8, rawIO);
+ assertThat(fileHeader.getVersionMadeBy()).isEqualTo(expectedVersionMadeBy);
+ } catch (Exception e) {
+ restoreOsSystemProperty();
+ }
+ }
+
private ZipParameters generateZipParameters() {
ZipParameters zipParameters = new ZipParameters();
zipParameters.setFileNameInZip(FILE_NAME_IN_ZIP);
@@ -276,11 +326,11 @@ public class FileHeaderFactoryTest {
}
private void verifyFileHeader(FileHeader fileHeader, ZipParameters zipParameters, boolean isSplitZip,
- int diskNumberStart, boolean aesExtraDataRecordPresent) {
+ int diskNumberStart, int versionNeededToExtract, boolean aesExtraDataRecordPresent) {
assertThat(fileHeader).isNotNull();
assertThat(fileHeader.getSignature()).isEqualTo(HeaderSignature.CENTRAL_DIRECTORY);
- assertThat(fileHeader.getVersionMadeBy()).isEqualTo(20);
- assertThat(fileHeader.getVersionNeededToExtract()).isEqualTo(20);
+ assertThat(fileHeader.getVersionMadeBy()).isEqualTo(819);
+ assertThat(fileHeader.getVersionNeededToExtract()).isEqualTo(versionNeededToExtract);
verifyCompressionMethod(fileHeader, zipParameters);
assertThat(fileHeader.isEncrypted()).isEqualTo(zipParameters.isEncryptFiles());
assertThat(fileHeader.getEncryptionMethod()).isEqualTo(zipParameters.isEncryptFiles()
@@ -393,4 +443,19 @@ public class FileHeaderFactoryTest {
assertThat(aesExtraDataRecord.getAesKeyStrength()).isEqualTo(aesKeyStrength);
}
+ private void changeOsSystemPropertyToWindows() {
+ System.setProperty("os.name", "windows");
+ }
+
+ private void changeOsSystemPropertyToUnix() {
+ System.setProperty("os.name", "nux");
+ }
+
+ private void changeOsSystemPropertyToMac() {
+ System.setProperty("os.name", "mac");
+ }
+
+ private void restoreOsSystemProperty() {
+ System.setProperty("os.name", ACTUAL_OS);
+ }
}
\ No newline at end of file
=====================================
src/test/java/net/lingala/zip4j/headers/HeaderReaderIT.java
=====================================
@@ -14,6 +14,7 @@ import net.lingala.zip4j.model.enums.EncryptionMethod;
import net.lingala.zip4j.model.enums.RandomAccessFileMode;
import net.lingala.zip4j.util.BitUtils;
import net.lingala.zip4j.util.InternalZipConstants;
+import net.lingala.zip4j.util.RawIO;
import org.junit.Test;
import java.io.File;
@@ -38,6 +39,7 @@ public class HeaderReaderIT extends AbstractIT {
private FileHeaderFactory fileHeaderFactory = new FileHeaderFactory();
private HeaderReader headerReader = new HeaderReader();
private HeaderWriter headerWriter = new HeaderWriter();
+ private RawIO rawIO = new RawIO();
@Test
public void testReadAllHeadersWith10Entries() throws IOException {
@@ -367,7 +369,7 @@ public class HeaderReaderIT extends AbstractIT {
List<FileHeader> fileHeaders = new ArrayList<>();
for (int i = 0; i < numberOfEntries; i++) {
zipParameters.setFileNameInZip(FILE_NAME_PREFIX + i);
- FileHeader fileHeader = fileHeaderFactory.generateFileHeader(zipParameters, false, 0, InternalZipConstants.CHARSET_UTF_8);
+ FileHeader fileHeader = fileHeaderFactory.generateFileHeader(zipParameters, false, 0, InternalZipConstants.CHARSET_UTF_8, rawIO);
fileHeaders.add(fileHeader);
}
return fileHeaders;
=====================================
src/test/java/net/lingala/zip4j/headers/HeaderUtilTest.java
=====================================
@@ -3,6 +3,7 @@ package net.lingala.zip4j.headers;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.model.CentralDirectory;
import net.lingala.zip4j.model.FileHeader;
+import net.lingala.zip4j.model.Zip64ExtendedInfo;
import net.lingala.zip4j.model.ZipModel;
import net.lingala.zip4j.util.InternalZipConstants;
import org.junit.Rule;
@@ -200,7 +201,7 @@ public class HeaderUtilTest {
public void testGetIndexOfFileHeaderGetsIndexSuccessfully() throws ZipException {
String fileNamePrefix = "FILE_NAME_";
int numberOfEntriesToAdd = 10;
- List<FileHeader> fileHeadersInZipModel = generateFileHeaderWithFileNames(fileNamePrefix, numberOfEntriesToAdd);
+ List<FileHeader> fileHeadersInZipModel = generateFileHeaderWithFileNamesWithEmptyAndNullFileNames(fileNamePrefix, numberOfEntriesToAdd);
ZipModel zipModel = new ZipModel();
zipModel.getCentralDirectory().setFileHeaders(fileHeadersInZipModel);
@@ -265,13 +266,60 @@ public class HeaderUtilTest {
assertThat(HeaderUtil.decodeStringWithCharset(plainEncodedBytes, false, null)).isEqualTo(englishString);
}
+ @Test
+ public void testGetFileHeadersUnderDirectoryWhenNotDirectoryReturnsEmptyList() {
+ List<FileHeader> allFileHeaders = generateFileHeaderWithFileNames("header", 5);
+ FileHeader rootFileHeader = generateFileHeader("some_name");
+ rootFileHeader.setDirectory(false);
+
+ assertThat(HeaderUtil.getFileHeadersUnderDirectory(allFileHeaders, rootFileHeader)).isEmpty();
+ }
+
+ @Test
+ public void testGetFileHeadersUnderDirectoryReturnsFileHeadersUnderDirectory() {
+ List<FileHeader> allFileHeaders = generateFileHeaderWithFileNames("some_name/header", 5);
+ allFileHeaders.add(generateFileHeader("some_name/"));
+ allFileHeaders.add(generateFileHeader("some_other_name.txt"));
+ FileHeader rootFileHeader = generateFileHeader("some_name/");
+ rootFileHeader.setDirectory(true);
+
+ List<FileHeader> filHeadersUnderDirectory = HeaderUtil.getFileHeadersUnderDirectory(allFileHeaders, rootFileHeader);
+ assertThat(filHeadersUnderDirectory).hasSize(6);
+ for (FileHeader fileHeader : filHeadersUnderDirectory) {
+ assertThat(fileHeader)
+ .withFailMessage("file header with name some_other_name.txt should not exist")
+ .isNotEqualTo("some_other_name.txt");
+ }
+ }
+
+ @Test
+ public void testGetUncompressedSizeOfAllFileHeaders() {
+ FileHeader fileHeader1 = generateFileHeader("1");
+ fileHeader1.setUncompressedSize(1000);
+ FileHeader fileHeader2 = generateFileHeader("2");
+ fileHeader2.setUncompressedSize(2000);
+ FileHeader fileHeader3 = generateFileHeader("3");
+ Zip64ExtendedInfo zip64ExtendedInfo = new Zip64ExtendedInfo();
+ zip64ExtendedInfo.setUncompressedSize(3000);
+ fileHeader3.setZip64ExtendedInfo(zip64ExtendedInfo);
+ fileHeader3.setUncompressedSize(0);
+ List<FileHeader> fileHeaders = Arrays.asList(fileHeader1, fileHeader2, fileHeader3);
+
+ assertThat(HeaderUtil.getTotalUncompressedSizeOfAllFileHeaders(fileHeaders)).isEqualTo(6000);
+ }
+
+ private List<FileHeader> generateFileHeaderWithFileNamesWithEmptyAndNullFileNames(String fileNamePrefix, int numberOfEntriesToAdd) {
+ List<FileHeader> fileHeaders = generateFileHeaderWithFileNames(fileNamePrefix, numberOfEntriesToAdd);
+ fileHeaders.add(generateFileHeader(""));
+ fileHeaders.add(generateFileHeader(null));
+ return fileHeaders;
+ }
+
private List<FileHeader> generateFileHeaderWithFileNames(String fileNamePrefix, int numberOfEntriesToAdd) {
List<FileHeader> fileHeaders = new ArrayList<>();
for (int i = 0; i < numberOfEntriesToAdd; i++) {
fileHeaders.add(generateFileHeader(fileNamePrefix + i));
}
- fileHeaders.add(generateFileHeader(""));
- fileHeaders.add(generateFileHeader(null));
return fileHeaders;
}
=====================================
src/test/java/net/lingala/zip4j/util/FileUtilsIT.java
=====================================
@@ -17,6 +17,8 @@ import java.io.RandomAccessFile;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
@@ -114,6 +116,21 @@ public class FileUtilsIT extends AbstractIT {
assertThat(FileUtils.isSymbolicLink(linkFile.toFile()));
}
+ @Test
+ public void testGetFilesInDirectoryRecursiveWithExcludeFileFilter() throws IOException {
+ File rootFolder = TestUtils.getTestFileFromResources("");
+ List<File> filesToExclude = Arrays.asList(
+ TestUtils.getTestFileFromResources("бореиская.txt"),
+ TestUtils.getTestFileFromResources("sample_directory/favicon.ico")
+ );
+ List<File> allFiles = FileUtils.getFilesInDirectoryRecursive(rootFolder, true, true, filesToExclude::contains);
+
+ assertThat(allFiles).hasSize(10);
+ for (File file : allFiles) {
+ assertThat(filesToExclude).doesNotContain(file);
+ }
+ }
+
private void testInvalidOffsetsScenario(int start, int offset) throws IOException {
expectedException.expectMessage("invalid offsets");
expectedException.expect(ZipException.class);
=====================================
src/test/java/net/lingala/zip4j/util/FileUtilsTestLinuxAndMac.java
=====================================
@@ -90,6 +90,11 @@ public class FileUtilsTestLinuxAndMac {
testGetFileAttributesGetsAsDefined(true);
}
+ @Test
+ public void testIsWindowsReturnsFalse() {
+ assertThat(FileUtils.isWindows()).isFalse();
+ }
+
private void testGetFileAttributesGetsAsDefined(boolean isDirectory) throws IOException {
File file = mock(File.class);
Path path = mock(Path.class);
=====================================
src/test/java/net/lingala/zip4j/util/FileUtilsTestWindows.java
=====================================
@@ -89,6 +89,11 @@ public class FileUtilsTestWindows {
assertThat(attributes).contains(0, 0, 0, 0);
}
+ @Test
+ public void testIsWindowsReturnsTrue() {
+ assertThat(FileUtils.isWindows()).isTrue();
+ }
+
@Test
public void testGetFileAttributesReturnsAttributesAsDefined() throws IOException {
File file = mock(File.class);
=====================================
src/test/java/net/lingala/zip4j/util/ZipVersionUtilsTest.java
=====================================
@@ -0,0 +1,79 @@
+package net.lingala.zip4j.util;
+
+import net.lingala.zip4j.headers.VersionNeededToExtract;
+import net.lingala.zip4j.model.ZipParameters;
+import net.lingala.zip4j.model.enums.CompressionMethod;
+import net.lingala.zip4j.model.enums.EncryptionMethod;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class ZipVersionUtilsTest {
+
+ private static final String ACTUAL_OS = System.getProperty("os.name");
+
+ private RawIO rawIO = new RawIO();
+
+ @Before
+ public void setup() {
+ System.setProperty("os.name", "linux");
+ }
+
+ @After
+ public void cleanup() {
+ System.setProperty("os.name", ACTUAL_OS);
+ }
+
+ @Test
+ public void testDetermineVersionMadeByUnix() {
+ assertThat(ZipVersionUtils.determineVersionMadeBy(new ZipParameters(), rawIO)).isEqualTo(819);
+ }
+
+ @Test
+ public void testDetermineVersionMadeByWindows() {
+ changeOsSystemPropertyToWindows();
+ assertThat(ZipVersionUtils.determineVersionMadeBy(new ZipParameters(), rawIO)).isEqualTo(51);
+ }
+
+ @Test
+ public void testDetermineVersionMadeByWindowsAndUnixModeOn() {
+ ZipParameters zipParameters = new ZipParameters();
+ zipParameters.setUnixMode(true);
+ assertThat(ZipVersionUtils.determineVersionMadeBy(zipParameters, rawIO)).isEqualTo(819);
+ }
+
+ @Test
+ public void testDetermineVersionNeededToExtractDefault() {
+ ZipParameters zipParameters = new ZipParameters();
+ zipParameters.setCompressionMethod(CompressionMethod.STORE);
+ assertThat(ZipVersionUtils.determineVersionNeededToExtract(zipParameters)).isEqualTo(VersionNeededToExtract.DEFAULT);
+ }
+
+ @Test
+ public void testDetermineVersionNeededToExtractDefalte() {
+ ZipParameters zipParameters = new ZipParameters();
+ zipParameters.setCompressionMethod(CompressionMethod.DEFLATE);
+ assertThat(ZipVersionUtils.determineVersionNeededToExtract(zipParameters)).isEqualTo(VersionNeededToExtract.DEFLATE_COMPRESSED);
+ }
+
+ @Test
+ public void testDetermineVersionNeededToExtractZip64() {
+ ZipParameters zipParameters = new ZipParameters();
+ zipParameters.setEntrySize(InternalZipConstants.ZIP_64_SIZE_LIMIT + 10);
+ assertThat(ZipVersionUtils.determineVersionNeededToExtract(zipParameters)).isEqualTo(VersionNeededToExtract.ZIP_64_FORMAT);
+ }
+
+ @Test
+ public void testDetermineVersionNeededToExtractAES() {
+ ZipParameters zipParameters = new ZipParameters();
+ zipParameters.setEncryptFiles(true);
+ zipParameters.setEncryptionMethod(EncryptionMethod.AES);
+ assertThat(ZipVersionUtils.determineVersionNeededToExtract(zipParameters)).isEqualTo(VersionNeededToExtract.AES_ENCRYPTED);
+ }
+
+ private void changeOsSystemPropertyToWindows() {
+ System.setProperty("os.name", "windows");
+ }
+}
\ No newline at end of file
View it on GitLab: https://salsa.debian.org/java-team/zip4j/-/commit/a71711856e15238e039454193b9c9634c67fa703
--
View it on GitLab: https://salsa.debian.org/java-team/zip4j/-/commit/a71711856e15238e039454193b9c9634c67fa703
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/20200525/46645a66/attachment.html>
More information about the pkg-java-commits
mailing list