Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
Expand Down Expand Up @@ -992,6 +993,14 @@ private static void unpackEntries(TarArchiveInputStream tis,
+ " would create entry outside of " + outputDir);
}

if (entry.isSymbolicLink() || entry.isLink()) {
String canonicalTargetPath = getCanonicalPath(entry.getLinkName(), outputDir);
if (!canonicalTargetPath.startsWith(targetDirPath)) {
throw new IOException(
"expanding " + entry.getName() + " would create entry outside of " + outputDir);
}
}

if (entry.isDirectory()) {
File subDir = new File(outputDir, entry.getName());
if (!subDir.mkdirs() && !subDir.isDirectory()) {
Expand All @@ -1007,10 +1016,12 @@ private static void unpackEntries(TarArchiveInputStream tis,
}

if (entry.isSymbolicLink()) {
// Create symbolic link relative to tar parent dir
Files.createSymbolicLink(FileSystems.getDefault()
.getPath(outputDir.getPath(), entry.getName()),
FileSystems.getDefault().getPath(entry.getLinkName()));
// Create symlink with canonical target path to ensure that we don't extract
// outside targetDirPath
String canonicalTargetPath = getCanonicalPath(entry.getLinkName(), outputDir);
Files.createSymbolicLink(
FileSystems.getDefault().getPath(outputDir.getPath(), entry.getName()),
FileSystems.getDefault().getPath(canonicalTargetPath));
return;
}

Expand All @@ -1022,14 +1033,29 @@ private static void unpackEntries(TarArchiveInputStream tis,
}

if (entry.isLink()) {
File src = new File(outputDir, entry.getLinkName());
String canonicalTargetPath = getCanonicalPath(entry.getLinkName(), outputDir);
File src = new File(canonicalTargetPath);
HardLink.createHardLink(src, outputFile);
return;
}

org.apache.commons.io.FileUtils.copyToFile(tis, outputFile);
}

/**
* Gets the canonical path for the given path.
*
* @param path The path for which the canonical path needs to be computed.
* @param parentDir The parent directory to use if the path is a relative path.
* @return The canonical path of the given path.
*/
private static String getCanonicalPath(String path, File parentDir) throws IOException {
java.nio.file.Path targetPath = Paths.get(path);
return (targetPath.isAbsolute() ?
new File(path) :
new File(parentDir, path)).getCanonicalPath();
}

/**
* Class for creating hardlinks.
* Supports Unix, WindXP.
Expand Down
Loading