Skip to content

Commit 826d13a

Browse files
jojochuangGauthamBanasandra
authored andcommitted
HADOOP-18155. Refactor tests in TestFileUtil (#4063)
(cherry picked from commit d0fa9b5) Conflicts: hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FileUtil.java hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestFileUtil.java Co-authored-by: Gautham B A <gautham.bangalore@gmail.com> (cherry picked from commit 743db6e)
1 parent d09ca8b commit 826d13a

File tree

2 files changed

+271
-159
lines changed

2 files changed

+271
-159
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
@@ -40,6 +40,7 @@
4040
import java.nio.file.AccessDeniedException;
4141
import java.nio.file.FileSystems;
4242
import java.nio.file.Files;
43+
import java.nio.file.Paths;
4344
import java.util.ArrayList;
4445
import java.util.Enumeration;
4546
import java.util.List;
@@ -971,6 +972,14 @@ private static void unpackEntries(TarArchiveInputStream tis,
971972
+ " would create entry outside of " + outputDir);
972973
}
973974

975+
if (entry.isSymbolicLink() || entry.isLink()) {
976+
String canonicalTargetPath = getCanonicalPath(entry.getLinkName(), outputDir);
977+
if (!canonicalTargetPath.startsWith(targetDirPath)) {
978+
throw new IOException(
979+
"expanding " + entry.getName() + " would create entry outside of " + outputDir);
980+
}
981+
}
982+
974983
if (entry.isDirectory()) {
975984
File subDir = new File(outputDir, entry.getName());
976985
if (!subDir.mkdirs() && !subDir.isDirectory()) {
@@ -986,10 +995,12 @@ private static void unpackEntries(TarArchiveInputStream tis,
986995
}
987996

988997
if (entry.isSymbolicLink()) {
989-
// Create symbolic link relative to tar parent dir
990-
Files.createSymbolicLink(FileSystems.getDefault()
991-
.getPath(outputDir.getPath(), entry.getName()),
992-
FileSystems.getDefault().getPath(entry.getLinkName()));
998+
// Create symlink with canonical target path to ensure that we don't extract
999+
// outside targetDirPath
1000+
String canonicalTargetPath = getCanonicalPath(entry.getLinkName(), outputDir);
1001+
Files.createSymbolicLink(
1002+
FileSystems.getDefault().getPath(outputDir.getPath(), entry.getName()),
1003+
FileSystems.getDefault().getPath(canonicalTargetPath));
9931004
return;
9941005
}
9951006

@@ -1001,7 +1012,8 @@ private static void unpackEntries(TarArchiveInputStream tis,
10011012
}
10021013

10031014
if (entry.isLink()) {
1004-
File src = new File(outputDir, entry.getLinkName());
1015+
String canonicalTargetPath = getCanonicalPath(entry.getLinkName(), outputDir);
1016+
File src = new File(canonicalTargetPath);
10051017
HardLink.createHardLink(src, outputFile);
10061018
return;
10071019
}
@@ -1019,6 +1031,20 @@ private static void unpackEntries(TarArchiveInputStream tis,
10191031
}
10201032
}
10211033

1034+
/**
1035+
* Gets the canonical path for the given path.
1036+
*
1037+
* @param path The path for which the canonical path needs to be computed.
1038+
* @param parentDir The parent directory to use if the path is a relative path.
1039+
* @return The canonical path of the given path.
1040+
*/
1041+
private static String getCanonicalPath(String path, File parentDir) throws IOException {
1042+
java.nio.file.Path targetPath = Paths.get(path);
1043+
return (targetPath.isAbsolute() ?
1044+
new File(path) :
1045+
new File(parentDir, path)).getCanonicalPath();
1046+
}
1047+
10221048
/**
10231049
* Class for creating hardlinks.
10241050
* Supports Unix, WindXP.

0 commit comments

Comments
 (0)