This commit is contained in:
Looly
2020-11-13 17:54:42 +08:00
parent 1a0c9a3b51
commit 99eeb30ffe
13 changed files with 222 additions and 116 deletions

View File

@@ -306,6 +306,7 @@ public class FileUtil extends PathUtil {
/**
* 创建File对象<br>
* 根据的路径构建文件在Win下直接构建在Linux下拆分路径单独构建
* 此方法会检查slip漏洞漏洞说明见http://blog.nsfocus.net/zip-slip-2/
*
* @param parent 父文件对象
@@ -316,7 +317,7 @@ public class FileUtil extends PathUtil {
if (StrUtil.isBlank(path)) {
throw new NullPointerException("File path is blank!");
}
return checkSlip(parent, new File(parent, path));
return checkSlip(parent, buildFile(parent, path));
}
/**
@@ -3277,4 +3278,34 @@ public class FileUtil extends PathUtil {
public static void tail(File file, Charset charset) {
tail(file, charset, Tailer.CONSOLE_HANDLER);
}
/**
* 根据压缩包中的路径构建目录结构在Win下直接构建在Linux下拆分路径单独构建
*
* @param outFile 最外部路径
* @param fileName 文件名,可以包含路径
* @return 文件或目录
* @since 5.0.5
*/
private static File buildFile(File outFile, String fileName) {
// 替换Windows路径分隔符为Linux路径分隔符便于统一处理
fileName = fileName.replace('\\', '/');
if (false == FileUtil.isWindows()
// 检查文件名中是否包含"/",不考虑以"/"结尾的情况
&& fileName.lastIndexOf(CharUtil.SLASH, fileName.length() - 2) > 0) {
// 在Linux下多层目录创建存在问题/会被当成文件名的一部分,此处做处理
// 使用/拆分路径zip中无\),级联创建父目录
final List<String> pathParts = StrUtil.split(fileName, '/', false, true);
final int lastPartIndex = pathParts.size() - 1;//目录个数
for (int i = 0; i < lastPartIndex; i++) {
//由于路径拆分slip不检查在最后一步检查
outFile = new File(outFile, pathParts.get(i));
}
//noinspection ResultOfMethodCallIgnored
outFile.mkdirs();
// 最后一个部分如果非空,作为文件名
fileName = pathParts.get(lastPartIndex);
}
return new File(outFile, fileName);
}
}

View File

@@ -471,7 +471,7 @@ public class ZipUtil {
while (em.hasMoreElements()) {
zipEntry = em.nextElement();
// FileUtil.file会检查slip漏洞漏洞说明见http://blog.nsfocus.net/zip-slip-2/
outItemFile = buildFile(outFile, zipEntry.getName());
outItemFile = FileUtil.file(outFile, zipEntry.getName());
if (zipEntry.isDirectory()) {
// 创建对应目录
//noinspection ResultOfMethodCallIgnored
@@ -1106,36 +1106,6 @@ public class ZipUtil {
throw new IORuntimeException(e);
}
}
/**
* 根据压缩包中的路径构建目录结构在Win下直接构建在Linux下拆分路径单独构建
*
* @param outFile 最外部路径
* @param fileName 文件名,可以包含路径
* @return 文件或目录
* @since 5.0.5
*/
private static File buildFile(File outFile, String fileName) {
// 替换Windows路径分隔符为Linux路径分隔符便于统一处理
fileName = fileName.replace('\\', '/');
if (false == FileUtil.isWindows()
// 检查文件名中是否包含"/",不考虑以"/"结尾的情况
&& fileName.lastIndexOf(CharUtil.SLASH, fileName.length() - 2) > 0) {
// 在Linux下多层目录创建存在问题/会被当成文件名的一部分,此处做处理
// 使用/拆分路径zip中无\),级联创建父目录
final List<String> pathParts = StrUtil.split(fileName, '/', false, true);
final int lastPartIndex = pathParts.size() - 1;//目录个数
for (int i = 0; i < lastPartIndex; i++) {
//由于路径拆分slip不检查在最后一步检查
outFile = new File(outFile, pathParts.get(i));
}
//noinspection ResultOfMethodCallIgnored
outFile.mkdirs();
// 最后一个部分如果非空,作为文件名
fileName = pathParts.get(lastPartIndex);
}
return FileUtil.file(outFile, fileName);
}
// ---------------------------------------------------------------------------------------------- Private method end
}