Skip to content
Commits on Source (7)
......@@ -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.3</version>
<version>2.1.4</version>
</dependency>
~~~~
......
zip4j (2.1.4-1) unstable; urgency=medium
* New upstream version 2.1.4
* Running tests during build.
-- Andrius Merkys <merkys@debian.org> Fri, 20 Sep 2019 01:30:35 -0400
zip4j (2.1.3-1) unstable; urgency=medium
* New upstream version 2.1.3
......
......@@ -8,6 +8,10 @@ Build-Depends:
debhelper (>= 12),
default-jdk,
maven-debian-helper (>= 2.1),
junit4,
libpowermock-java,
libassertj-core-java,
libmockito-java,
Standards-Version: 4.3.0
Vcs-Git: https://salsa.debian.org/java-team/zip4j.git
Vcs-Browser: https://salsa.debian.org/java-team/zip4j
......
junit junit * * * *
org.apache.maven.plugins maven-failsafe-plugin * * * *
org.apache.maven.plugins maven-gpg-plugin * * * *
org.apache.maven.plugins maven-javadoc-plugin * * * *
org.apache.maven.plugins maven-source-plugin * * * *
org.assertj assertj-core * * * *
org.mockito mockito-core * * * *
org.powermock powermock-api-mockito2 * * * *
org.powermock powermock-module-junit4 * * * *
org.sonatype.plugins nexus-staging-maven-plugin * * * *
org.powermock powermock-api-mockito2 * * * *
......@@ -2,5 +2,3 @@
# For example:
# maven.test.skip=true
# project.build.sourceEncoding=UTF-8
maven.test.skip=true
junit junit jar s/4\..*/4\.x/ * *
net.lingala.zip4j zip4j jar s/.*/debian/ * *
This diff is collapsed.
remove-incompatible-tests.patch
......@@ -6,7 +6,7 @@
<groupId>net.lingala.zip4j</groupId>
<artifactId>zip4j</artifactId>
<version>2.1.4-SNAPSHOT</version>
<version>2.1.5-SNAPSHOT</version>
<name>Zip4j</name>
<description>Zip4j - A Java library for zip files and streams</description>
......
......@@ -27,7 +27,6 @@ import net.lingala.zip4j.model.LocalFileHeader;
import net.lingala.zip4j.model.enums.AesVersion;
import net.lingala.zip4j.model.enums.CompressionMethod;
import net.lingala.zip4j.model.enums.EncryptionMethod;
import net.lingala.zip4j.util.BitUtils;
import net.lingala.zip4j.util.InternalZipConstants;
import java.io.IOException;
......@@ -48,8 +47,9 @@ public class ZipInputStream extends InputStream {
private char[] password;
private LocalFileHeader localFileHeader;
private CRC32 crc32 = new CRC32();
private boolean extraDataRecordReadForThisEntry = false;
private byte[] endOfEntryBuffer;
private boolean extraDataRecordReadForThisEntry = false;
private boolean canSkipExtendedLocalFileHeader = false;
public ZipInputStream(InputStream inputStream) {
this(inputStream, null);
......@@ -82,6 +82,9 @@ public class ZipInputStream extends InputStream {
localFileHeader.setCrc(fileHeader.getCrc());
localFileHeader.setCompressedSize(fileHeader.getCompressedSize());
localFileHeader.setUncompressedSize(fileHeader.getUncompressedSize());
canSkipExtendedLocalFileHeader = true;
} else {
canSkipExtendedLocalFileHeader = false;
}
if (!isZipEntryDirectory(localFileHeader.getFileName())) {
......@@ -206,7 +209,7 @@ public class ZipInputStream extends InputStream {
}
private void readExtendedLocalFileHeaderIfPresent() throws IOException {
if (!isExtendedLocalFileHeaderPresent(localFileHeader)) {
if (!localFileHeader.isDataDescriptorExists() || canSkipExtendedLocalFileHeader) {
return;
}
......@@ -217,11 +220,6 @@ public class ZipInputStream extends InputStream {
localFileHeader.setCrc(dataDescriptor.getCrc());
}
private boolean isExtendedLocalFileHeaderPresent(LocalFileHeader localFileHeader) {
byte[] generalPurposeFlags = localFileHeader.getGeneralPurposeFlag();
return BitUtils.isBitSet(generalPurposeFlags[0], 3);
}
private void verifyLocalFileHeader(LocalFileHeader localFileHeader) throws IOException {
if (!isEntryDirectory(localFileHeader.getFileName())
&& localFileHeader.getCompressionMethod() == CompressionMethod.STORE
......@@ -278,7 +276,7 @@ public class ZipInputStream extends InputStream {
return localFileHeader.getUncompressedSize();
}
if (localFileHeader.isDataDescriptorExists()) {
if (localFileHeader.isDataDescriptorExists() && !canSkipExtendedLocalFileHeader) {
return -1;
}
......
......@@ -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).getCanonicalPath().startsWith(new File(outPath).getPath())) {
if (!new File(completePath).getCanonicalPath().startsWith(new File(outPath).getCanonicalPath())) {
throw new ZipException("illegal file name that breaks out of the target directory: "
+ fileHeader.getFileName());
}
......
......@@ -41,13 +41,13 @@ public class AddFolderToZipTask extends AbstractAddFileToZipTask<AddFolderToZipT
return calculateWorkForFiles(filesToAdd, taskParameters.zipParameters);
}
private void setDefaultFolderPath(AddFolderToZipTaskParameters taskParameters) {
private void setDefaultFolderPath(AddFolderToZipTaskParameters taskParameters) throws IOException {
String rootFolderPath;
File folderToAdd = taskParameters.folderToAdd;
if (taskParameters.zipParameters.isIncludeRootFolder()) {
rootFolderPath = folderToAdd.getParentFile().getPath();
rootFolderPath = folderToAdd.getParentFile().getCanonicalPath();
} else {
rootFolderPath = folderToAdd.getAbsolutePath();
rootFolderPath = folderToAdd.getCanonicalPath();
}
taskParameters.zipParameters.setDefaultFolderPath(rootFolderPath);
......
......@@ -31,7 +31,6 @@ public class ExtractAllFilesTask extends AbstractExtractFileTask<ExtractAllFiles
}
splitInputStream.prepareExtractionForFileHeader(fileHeader);
splitInputStream.skip(zipInputStream.getAvailableBytesInPushBackInputStream());
extractFile(zipInputStream, fileHeader, taskParameters.outputPath, null, progressMonitor);
verifyIfTaskIsCancelled();
......
......@@ -181,23 +181,25 @@ public class FileUtils {
return splitZipFiles;
}
public static String getRelativeFileName(String file, String rootFolderPath) {
public static String getRelativeFileName(String file, String rootFolderPath) throws ZipException {
String fileName;
try {
String fileCanonicalPath = new File(file).getCanonicalPath();
if (isStringNotNullAndNotEmpty(rootFolderPath)) {
File rootFolderFile = new File(rootFolderPath);
String rootFolderFileRef = rootFolderFile.getPath();
String rootFolderFileRef = rootFolderFile.getCanonicalPath();
if (!rootFolderFileRef.endsWith(FILE_SEPARATOR)) {
rootFolderFileRef += FILE_SEPARATOR;
}
String tmpFileName = file.substring(rootFolderFileRef.length());
String tmpFileName = fileCanonicalPath.substring(rootFolderFileRef.length());
if (tmpFileName.startsWith(System.getProperty("file.separator"))) {
tmpFileName = tmpFileName.substring(1);
}
File tmpFile = new File(file);
File tmpFile = new File(fileCanonicalPath);
if (tmpFile.isDirectory()) {
tmpFileName = tmpFileName.replaceAll("\\\\", "/");
......@@ -210,13 +212,16 @@ public class FileUtils {
fileName = tmpFileName;
} else {
File relFile = new File(file);
File relFile = new File(fileCanonicalPath);
if (relFile.isDirectory()) {
fileName = relFile.getName() + ZIP_FILE_SEPARATOR;
} else {
fileName = relFile.getName();
}
}
} catch (IOException e) {
throw new ZipException(e);
}
return fileName;
}
......
......@@ -194,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.getCanonicalPath());
zipFile.extractAll(outputFolder.getPath());
}
@Test
......@@ -557,6 +557,24 @@ public class AddFilesToZipIT extends AbstractIT {
ZipFileVerifier.verifyZipFileByExtractingAllFiles(generatedZipFile, PASSWORD, outputFolder, 13);
}
@Test
public void testAddFolderWithNotNormalizedPath() throws IOException {
ZipFile zipFile = new ZipFile(generatedZipFile);
ZipParameters parameters = new ZipParameters();
String folderToAddPath = TestUtils.getTestFileFromResources("").getPath()
+ InternalZipConstants.FILE_SEPARATOR + ".."
+ InternalZipConstants.FILE_SEPARATOR
+ TestUtils.getTestFileFromResources("").getName();
File folderToAdd = new File(folderToAddPath);
zipFile.addFolder(folderToAdd, parameters);
File fileToAdd = TestUtils.getTestFileFromResources("file_PDF_1MB.pdf");
zipFile.addFile(fileToAdd, parameters);
ZipFileVerifier.verifyZipFileByExtractingAllFiles(generatedZipFile, outputFolder, 13);
}
@Test
public void testAddStreamToZipThrowsExceptionWhenFileNameIsNull() throws IOException {
ZipFile zipFile = new ZipFile(generatedZipFile);
......
......@@ -34,7 +34,7 @@ public class ExtractZipFileIT extends AbstractIT {
ZipFile zipFile = new ZipFile(generatedZipFile);
zipFile.addFiles(FILES_TO_ADD, zipParameters);
zipFile.extractAll(outputFolder.getCanonicalPath());
zipFile.extractAll(outputFolder.getPath());
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.getCanonicalPath());
zipFile.extractAll(outputFolder.getPath());
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.getCanonicalPath());
zipFile.extractAll(outputFolder.getPath());
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.getCanonicalPath());
zipFile.extractAll(outputFolder.getPath());
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.getCanonicalPath());
zipFile.extractAll(outputFolder.getPath());
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.getCanonicalPath());
zipFile.extractAll(outputFolder.getPath());
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.getCanonicalPath());
zipFile.extractAll(outputFolder.getPath());
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.getCanonicalPath());
zipFile.extractAll(outputFolder.getPath());
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.getCanonicalPath());
zipFile.extractFile(fileHeader, outputFolder.getPath());
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.getCanonicalPath());
zipFile.extractFile(fileHeader, outputFolder.getPath());
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.getCanonicalPath(), newFileName);
zipFile.extractFile(fileHeader, outputFolder.getPath(), 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.getCanonicalPath());
zipFile.extractFile("test-files/sample_directory/favicon.ico", outputFolder.getPath());
File outputFile = getFileWithNameFrom(outputFolder, "favicon.ico");
ZipFileVerifier.verifyFileContent(TestUtils.getTestFileFromResources("sample_directory/favicon.ico"), outputFile);
......@@ -197,7 +197,7 @@ public class ExtractZipFileIT extends AbstractIT {
zipFile.addFolder(TestUtils.getTestFileFromResources(""), zipParameters);
String newFileName = "newFileName";
zipFile.extractFile("test-files/sample_directory/favicon.ico", outputFolder.getCanonicalPath(), newFileName);
zipFile.extractFile("test-files/sample_directory/favicon.ico", outputFolder.getPath(), newFileName);
File outputFile = getFileWithNameFrom(outputFolder, newFileName);
ZipFileVerifier.verifyFileContent(TestUtils.getTestFileFromResources("sample_directory/favicon.ico"), outputFile);
......@@ -211,7 +211,7 @@ public class ExtractZipFileIT extends AbstractIT {
try {
zipFile = new ZipFile(generatedZipFile, "WRONG_PASSWORD".toCharArray());
zipFile.extractAll(outputFolder.getCanonicalPath());
zipFile.extractAll(outputFolder.getPath());
fail("Should throw an exception");
} catch (ZipException e) {
assertThat(e).isNotNull();
......@@ -227,7 +227,7 @@ public class ExtractZipFileIT extends AbstractIT {
try {
zipFile = new ZipFile(generatedZipFile, "WRONG_PASSWORD".toCharArray());
zipFile.extractAll(outputFolder.getCanonicalPath());
zipFile.extractAll(outputFolder.getPath());
fail("Should throw an exception");
} catch (ZipException e) {
assertThat(e).isNotNull();
......@@ -244,7 +244,7 @@ public class ExtractZipFileIT extends AbstractIT {
try {
zipFile = new ZipFile(generatedZipFile, "WRONG_PASSWORD".toCharArray());
zipFile.extractAll(outputFolder.getCanonicalPath());
zipFile.extractAll(outputFolder.getPath());
fail("Should throw an exception");
} catch (ZipException e) {
assertThat(e).isNotNull();
......@@ -263,7 +263,7 @@ public class ExtractZipFileIT extends AbstractIT {
public void testExtractFilesForZipFileWhileWithCorruptExtraDataRecordLength() throws IOException {
ZipFile zipFile = new ZipFile(getTestArchiveFromResources("corrupt_extra_data_record_length.zip"));
zipFile.extractAll(outputFolder.getCanonicalPath());
zipFile.extractAll(outputFolder.getPath());
assertThat(zipFile.getFileHeaders()).hasSize(44);
assertThat(Files.walk(outputFolder.toPath()).filter(Files::isRegularFile)).hasSize(44);
......@@ -280,6 +280,16 @@ public class ExtractZipFileIT extends AbstractIT {
zipFile.extractAll(outputFolder.getCanonicalPath());
}
@Test
public void testExtractZipFileWithMissingExtendedLocalFileHeader() throws IOException {
ZipFile zipFile = new ZipFile(getTestArchiveFromResources("missing_exended_local_file_header.zip"));
zipFile.extractAll(outputFolder.getPath());
assertThat(zipFile.getFileHeaders()).hasSize(3);
assertThat(Files.walk(outputFolder.toPath()).filter(Files::isRegularFile)).hasSize(3);
}
private void verifyNumberOfFilesInOutputFolder(File outputFolder, int numberOfExpectedFiles) {
assertThat(outputFolder.listFiles()).hasSize(numberOfExpectedFiles);
}
......
......@@ -410,6 +410,14 @@ public class MiscZipFileIT extends AbstractIT {
}
}
@Test
public void testUnzipFileZipSlipWithNotNormalizedTarget() throws IOException {
ZipFile zipFile = new ZipFile(generatedZipFile, PASSWORD);
zipFile.addFiles(FILES_TO_ADD);
zipFile.extractAll(new File(outputFolder.getPath(),
".." + InternalZipConstants.FILE_SEPARATOR + outputFolder.getName()).getAbsolutePath());
}
@Test
public void testExtractFileDeletesOutputFileWhenWrongPassword() throws IOException {
ZipParameters zipParameters = createZipParameters(EncryptionMethod.ZIP_STANDARD, AesKeyStrength.KEY_STRENGTH_256);
......
......@@ -31,7 +31,7 @@ public class ZipFileVerifier {
assertThat(zipFileToExtract).exists();
ZipFile zipFile = new ZipFile(zipFileToExtract, password);
zipFile.extractAll(outputFolder.getCanonicalPath());
zipFile.extractAll(outputFolder.getPath());
assertThat(zipFile.getFileHeaders().size()).as("Number of file headers").isEqualTo(expectedNumberOfEntries);
List<File> extractedFiles = FileUtils.getFilesInDirectoryRecursive(outputFolder, true, true);
......
......@@ -247,7 +247,7 @@ public class FileUtilsTest {
}
@Test
public void testGetRelativeFileNameWhenRootFoldersAreNull() {
public void testGetRelativeFileNameWhenRootFoldersAreNull() throws ZipException {
assertThat(FileUtils.getRelativeFileName("somefile.txt", null)).isEqualTo("somefile.txt");
}
......