diff -Nru zip4j-2.11.3/debian/changelog zip4j-2.11.5/debian/changelog --- zip4j-2.11.3/debian/changelog 2023-01-30 07:59:02.000000000 +0000 +++ zip4j-2.11.5/debian/changelog 2023-02-24 13:46:32.000000000 +0000 @@ -1,3 +1,9 @@ +zip4j (2.11.5-1) unstable; urgency=medium + + * New upstream version 2.11.5 + + -- Andrius Merkys Fri, 24 Feb 2023 08:46:32 -0500 + zip4j (2.11.3-1) unstable; urgency=medium * New upstream version 2.11.3 diff -Nru zip4j-2.11.3/NOTICE zip4j-2.11.5/NOTICE --- zip4j-2.11.3/NOTICE 1970-01-01 00:00:00.000000000 +0000 +++ zip4j-2.11.5/NOTICE 2023-02-20 23:56:53.000000000 +0000 @@ -0,0 +1,2 @@ +Zip4j +Copyright 2019 and onwards Srikanth Reddy Lingala \ No newline at end of file diff -Nru zip4j-2.11.3/pom.xml zip4j-2.11.5/pom.xml --- zip4j-2.11.3/pom.xml 2023-01-26 01:18:04.000000000 +0000 +++ zip4j-2.11.5/pom.xml 2023-02-20 23:56:53.000000000 +0000 @@ -6,7 +6,7 @@ net.lingala.zip4j zip4j - 2.11.4-SNAPSHOT + 2.11.4 Zip4j Zip4j - A Java library for zip files and streams diff -Nru zip4j-2.11.3/README.md zip4j-2.11.5/README.md --- zip4j-2.11.3/README.md 2023-01-26 01:18:04.000000000 +0000 +++ zip4j-2.11.5/README.md 2023-02-20 23:56:53.000000000 +0000 @@ -71,7 +71,7 @@ net.lingala.zip4j zip4j - 2.11.3 + 2.11.5-SNAPSHOT ``` diff -Nru zip4j-2.11.3/src/main/java/net/lingala/zip4j/headers/HeaderReader.java zip4j-2.11.5/src/main/java/net/lingala/zip4j/headers/HeaderReader.java --- zip4j-2.11.3/src/main/java/net/lingala/zip4j/headers/HeaderReader.java 2023-01-26 01:18:04.000000000 +0000 +++ zip4j-2.11.5/src/main/java/net/lingala/zip4j/headers/HeaderReader.java 2023-02-20 23:56:53.000000000 +0000 @@ -66,6 +66,10 @@ public ZipModel readAllHeaders(RandomAccessFile zip4jRaf, Zip4jConfig zip4jConfig) throws IOException { + if (zip4jRaf.length() == 0) { + return new ZipModel(); + } + if (zip4jRaf.length() < ENDHDR) { throw new ZipException("Zip file size less than minimum expected zip file size. " + "Probably not a zip file or a corrupted zip file"); diff -Nru zip4j-2.11.3/src/main/java/net/lingala/zip4j/tasks/AbstractExtractFileTask.java zip4j-2.11.5/src/main/java/net/lingala/zip4j/tasks/AbstractExtractFileTask.java --- zip4j-2.11.3/src/main/java/net/lingala/zip4j/tasks/AbstractExtractFileTask.java 2023-01-26 01:18:04.000000000 +0000 +++ zip4j-2.11.5/src/main/java/net/lingala/zip4j/tasks/AbstractExtractFileTask.java 2023-02-20 23:56:53.000000000 +0000 @@ -59,14 +59,16 @@ throw new ZipException("Could not create directory: " + outputFile); } } - } else if (isSymbolicLink(fileHeader)) { + } else if (isSymbolicLink) { createSymLink(zipInputStream, fileHeader, outputFile, progressMonitor); } else { checkOutputDirectoryStructure(outputFile); unzipFile(zipInputStream, outputFile, progressMonitor, readBuff); } - UnzipUtil.applyFileAttributes(fileHeader, outputFile); + if (!isSymbolicLink) { + UnzipUtil.applyFileAttributes(fileHeader, outputFile); + } } private void assertCanonicalPathsAreSame(File outputFile, String outputPath, FileHeader fileHeader) @@ -128,6 +130,11 @@ try { Path linkTarget = Paths.get(symLinkPath); + if (outputFile.exists()) { + if (!outputFile.delete()) { + throw new ZipException("Could not delete existing symlink " + outputFile); + } + } Files.createSymbolicLink(outputFile.toPath(), linkTarget); } catch (NoSuchMethodError error) { try (OutputStream outputStream = new FileOutputStream(outputFile)) { diff -Nru zip4j-2.11.3/src/main/java/net/lingala/zip4j/util/FileUtils.java zip4j-2.11.5/src/main/java/net/lingala/zip4j/util/FileUtils.java --- zip4j-2.11.3/src/main/java/net/lingala/zip4j/util/FileUtils.java 2023-01-26 01:18:04.000000000 +0000 +++ zip4j-2.11.5/src/main/java/net/lingala/zip4j/util/FileUtils.java 2023-02-20 23:56:53.000000000 +0000 @@ -222,7 +222,7 @@ String rootPath = new File(fileToAdd.getParentFile().getCanonicalFile().getPath() + File.separator + fileToAdd.getCanonicalFile().getName()).getPath(); tmpFileName = rootPath.substring(rootFolderFileRef.length()); } else { - if (!fileToAdd.getCanonicalFile().toPath().startsWith(rootFolderFileRef)) { + if (!fileToAdd.getCanonicalFile().getPath().startsWith(rootFolderFileRef)) { tmpFileName = fileToAdd.getCanonicalFile().getParentFile().getName() + FILE_SEPARATOR + fileToAdd.getCanonicalFile().getName(); } else { tmpFileName = fileCanonicalPath.substring(rootFolderFileRef.length()); @@ -558,9 +558,17 @@ LinkOption.NOFOLLOW_LINKS); Set posixFilePermissions = posixFileAttributeView.readAttributes().permissions(); - fileAttributes[3] = setBitIfApplicable(Files.isRegularFile(file), fileAttributes[3], 7); - fileAttributes[3] = setBitIfApplicable(Files.isDirectory(file), fileAttributes[3], 6); - fileAttributes[3] = setBitIfApplicable(Files.isSymbolicLink(file), fileAttributes[3], 5); + boolean isSymlink = Files.isSymbolicLink(file); + if (isSymlink) { + // Mark as a regular file and not a directory if file is a symlink and even if the symlink points to a directory + fileAttributes[3] = BitUtils.setBit(fileAttributes[3], 7); + fileAttributes[3] = BitUtils.unsetBit(fileAttributes[3], 6); + } else { + fileAttributes[3] = setBitIfApplicable(Files.isRegularFile(file), fileAttributes[3], 7); + fileAttributes[3] = setBitIfApplicable(Files.isDirectory(file), fileAttributes[3], 6); + } + + fileAttributes[3] = setBitIfApplicable(isSymlink, fileAttributes[3], 5); fileAttributes[3] = setBitIfApplicable(posixFilePermissions.contains(OWNER_READ), fileAttributes[3], 0); fileAttributes[2] = setBitIfApplicable(posixFilePermissions.contains(OWNER_WRITE), fileAttributes[2], 7); fileAttributes[2] = setBitIfApplicable(posixFilePermissions.contains(OWNER_EXECUTE), fileAttributes[2], 6); diff -Nru zip4j-2.11.3/src/test/java/net/lingala/zip4j/AddFilesToZipIT.java zip4j-2.11.5/src/test/java/net/lingala/zip4j/AddFilesToZipIT.java --- zip4j-2.11.3/src/test/java/net/lingala/zip4j/AddFilesToZipIT.java 2023-01-26 01:18:04.000000000 +0000 +++ zip4j-2.11.5/src/test/java/net/lingala/zip4j/AddFilesToZipIT.java 2023-02-20 23:56:53.000000000 +0000 @@ -950,6 +950,22 @@ } @Test + public void testAddStreamToAnEmptyFileDoesNotThrowException() throws IOException { + if (!generatedZipFile.createNewFile()) { + throw new RuntimeException("Cannot create an empty file to test"); + } + File fileToAdd = TestUtils.getTestFileFromResources("sample.pdf"); + try (ZipFile zipFile = new ZipFile(generatedZipFile); + InputStream inputStream = Files.newInputStream(fileToAdd.toPath())) { + ZipParameters zipParameters = new ZipParameters(); + zipParameters.setFileNameInZip(fileToAdd.getName()); + zipFile.addStream(inputStream, zipParameters); + } + + ZipFileVerifier.verifyZipFileByExtractingAllFiles(generatedZipFile, outputFolder, 1); + } + + @Test public void testAddFolderWithCustomBufferSize() throws IOException { ZipFile zipFile = new ZipFile(generatedZipFile); zipFile.setBufferSize(16 * 1024); diff -Nru zip4j-2.11.3/src/test/java/net/lingala/zip4j/ExtractZipFileIT.java zip4j-2.11.5/src/test/java/net/lingala/zip4j/ExtractZipFileIT.java --- zip4j-2.11.3/src/test/java/net/lingala/zip4j/ExtractZipFileIT.java 2023-01-26 01:18:04.000000000 +0000 +++ zip4j-2.11.5/src/test/java/net/lingala/zip4j/ExtractZipFileIT.java 2023-02-20 23:56:53.000000000 +0000 @@ -19,6 +19,7 @@ import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; +import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; @@ -329,6 +330,22 @@ } @Test + public void testSymlinkToDirectoryMaintainsSymlink() throws IOException { + verifyZipFileByExtractingAllFiles(getTestArchiveFromResources("zipWithLinkToDirAndFolder.zip"), null, outputFolder, 5, false); + + Path aDirectory = Paths.get(outputFolder.getPath(), "a"); + Path symlinkToDir = Paths.get(outputFolder.getPath(), "b"); + Path aFile = Paths.get(outputFolder.getPath(), "c"); + Path symlinkToFile = Paths.get(outputFolder.getPath(), "d"); + assertThat(aDirectory).isDirectory(); + assertThat(Files.isSymbolicLink(symlinkToDir)).isTrue(); + assertThat(aFile).isRegularFile(); + assertThat(symlinkToFile).isSymbolicLink(); + assertThat(Files.readSymbolicLink(symlinkToDir)).isEqualTo(aDirectory.getFileName()); + assertThat(Files.readSymbolicLink(symlinkToFile)).isEqualTo(aFile.getFileName()); + } + + @Test public void testExtractFilesThrowsExceptionForWrongPasswordForAes() throws IOException { ZipParameters zipParameters = createZipParameters(EncryptionMethod.AES, AesKeyStrength.KEY_STRENGTH_256); ZipFile zipFile = new ZipFile(generatedZipFile, PASSWORD); Binary files /tmp/tmp8v5sa88k/U7ACkuZ9Oy/zip4j-2.11.3/src/test/resources/test-archives/zipWithLinkToDirAndFolder.zip and /tmp/tmp8v5sa88k/xWt_dNmPRC/zip4j-2.11.5/src/test/resources/test-archives/zipWithLinkToDirAndFolder.zip differ