Skip to content

Commit

Permalink
#486 Set symlink as a file even if it points to directory
Browse files Browse the repository at this point in the history
  • Loading branch information
srikanth-lingala committed Feb 9, 2023
1 parent 7f74287 commit a28ca75
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,16 @@ protected void extractFile(ZipInputStream zipInputStream, FileHeader fileHeader,
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)
Expand Down Expand Up @@ -128,6 +130,11 @@ private void createSymLink(ZipInputStream zipInputStream, FileHeader fileHeader,

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)) {
Expand Down
14 changes: 11 additions & 3 deletions src/main/java/net/lingala/zip4j/util/FileUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -558,9 +558,17 @@ private static byte[] getPosixFileAttributes(Path file) {
LinkOption.NOFOLLOW_LINKS);
Set<PosixFilePermission> 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);
Expand Down
17 changes: 17 additions & 0 deletions src/test/java/net/lingala/zip4j/ExtractZipFileIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -328,6 +329,22 @@ public void testExtractFileWithFileNameAndNewFileNameExtractsSymlinkWhenSymlinkE
assertThat(outputFolder.listFiles()[0].getName()).isEqualTo(newFileName);
}

@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);
Expand Down
Binary file not shown.

0 comments on commit a28ca75

Please sign in to comment.