Skip to content

Commit 50a5971

Browse files
jojochuangGauthamBanasandra
authored andcommitted
HADOOP-18155. Refactor tests in TestFileUtil (apache#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 Change-Id: I2bba28c56dd08da315856066b58b1778b67bfb45 Co-authored-by: Gautham B A <[email protected]>
1 parent 2debdfc commit 50a5971

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
@@ -38,6 +38,7 @@
3838
import java.nio.file.AccessDeniedException;
3939
import java.nio.file.FileSystems;
4040
import java.nio.file.Files;
41+
import java.nio.file.Paths;
4142
import java.util.ArrayList;
4243
import java.util.Enumeration;
4344
import java.util.List;
@@ -970,6 +971,14 @@ private static void unpackEntries(TarArchiveInputStream tis,
970971
+ " would create entry outside of " + outputDir);
971972
}
972973

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

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

@@ -1000,14 +1011,29 @@ private static void unpackEntries(TarArchiveInputStream tis,
10001011
}
10011012

10021013
if (entry.isLink()) {
1003-
File src = new File(outputDir, entry.getLinkName());
1014+
String canonicalTargetPath = getCanonicalPath(entry.getLinkName(), outputDir);
1015+
File src = new File(canonicalTargetPath);
10041016
HardLink.createHardLink(src, outputFile);
10051017
return;
10061018
}
10071019

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

1023+
/**
1024+
* Gets the canonical path for the given path.
1025+
*
1026+
* @param path The path for which the canonical path needs to be computed.
1027+
* @param parentDir The parent directory to use if the path is a relative path.
1028+
* @return The canonical path of the given path.
1029+
*/
1030+
private static String getCanonicalPath(String path, File parentDir) throws IOException {
1031+
java.nio.file.Path targetPath = Paths.get(path);
1032+
return (targetPath.isAbsolute() ?
1033+
new File(path) :
1034+
new File(parentDir, path)).getCanonicalPath();
1035+
}
1036+
10111037
/**
10121038
* Class for creating hardlinks.
10131039
* Supports Unix, WindXP.

0 commit comments

Comments
 (0)