Skip to content

Commit d0fa9b5

Browse files
HADOOP-18155. Refactor tests in TestFileUtil (apache#4053)
1 parent 383b734 commit d0fa9b5

File tree

2 files changed

+275
-163
lines changed

2 files changed

+275
-163
lines changed

hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FileUtil.java

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import java.nio.file.FileSystems;
4040
import java.nio.file.Files;
4141
import java.nio.file.LinkOption;
42+
import java.nio.file.Paths;
4243
import java.util.ArrayList;
4344
import java.util.Enumeration;
4445
import java.util.List;
@@ -992,6 +993,14 @@ private static void unpackEntries(TarArchiveInputStream tis,
992993
+ " would create entry outside of " + outputDir);
993994
}
994995

996+
if (entry.isSymbolicLink() || entry.isLink()) {
997+
String canonicalTargetPath = getCanonicalPath(entry.getLinkName(), outputDir);
998+
if (!canonicalTargetPath.startsWith(targetDirPath)) {
999+
throw new IOException(
1000+
"expanding " + entry.getName() + " would create entry outside of " + outputDir);
1001+
}
1002+
}
1003+
9951004
if (entry.isDirectory()) {
9961005
File subDir = new File(outputDir, entry.getName());
9971006
if (!subDir.mkdirs() && !subDir.isDirectory()) {
@@ -1007,10 +1016,12 @@ private static void unpackEntries(TarArchiveInputStream tis,
10071016
}
10081017

10091018
if (entry.isSymbolicLink()) {
1010-
// Create symbolic link relative to tar parent dir
1011-
Files.createSymbolicLink(FileSystems.getDefault()
1012-
.getPath(outputDir.getPath(), entry.getName()),
1013-
FileSystems.getDefault().getPath(entry.getLinkName()));
1019+
// Create symlink with canonical target path to ensure that we don't extract
1020+
// outside targetDirPath
1021+
String canonicalTargetPath = getCanonicalPath(entry.getLinkName(), outputDir);
1022+
Files.createSymbolicLink(
1023+
FileSystems.getDefault().getPath(outputDir.getPath(), entry.getName()),
1024+
FileSystems.getDefault().getPath(canonicalTargetPath));
10141025
return;
10151026
}
10161027

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

10241035
if (entry.isLink()) {
1025-
File src = new File(outputDir, entry.getLinkName());
1036+
String canonicalTargetPath = getCanonicalPath(entry.getLinkName(), outputDir);
1037+
File src = new File(canonicalTargetPath);
10261038
HardLink.createHardLink(src, outputFile);
10271039
return;
10281040
}
10291041

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

1045+
/**
1046+
* Gets the canonical path for the given path.
1047+
*
1048+
* @param path The path for which the canonical path needs to be computed.
1049+
* @param parentDir The parent directory to use if the path is a relative path.
1050+
* @return The canonical path of the given path.
1051+
*/
1052+
private static String getCanonicalPath(String path, File parentDir) throws IOException {
1053+
java.nio.file.Path targetPath = Paths.get(path);
1054+
return (targetPath.isAbsolute() ?
1055+
new File(path) :
1056+
new File(parentDir, path)).getCanonicalPath();
1057+
}
1058+
10331059
/**
10341060
* Class for creating hardlinks.
10351061
* Supports Unix, WindXP.

0 commit comments

Comments
 (0)