diff --git a/core/core-backend/src/main/java/io/dataease/exportCenter/manage/ExportCenterManage.java b/core/core-backend/src/main/java/io/dataease/exportCenter/manage/ExportCenterManage.java index 4b6805e14b..5d03a61ae2 100644 --- a/core/core-backend/src/main/java/io/dataease/exportCenter/manage/ExportCenterManage.java +++ b/core/core-backend/src/main/java/io/dataease/exportCenter/manage/ExportCenterManage.java @@ -138,7 +138,7 @@ public class ExportCenterManage implements BaseExportApi { exportTask.setExportMachineName(hostName()); exportTask.setExportTime(System.currentTimeMillis()); exportTaskMapper.updateById(exportTask); - FileUtils.deleteDirectoryRecursively(resolveExportTaskDirectory(id)); + FileUtils.deleteDirectoryRecursively(resolveExportBasePath(), resolveExportTaskDirectory(id)); if (exportTask.getExportFromType().equalsIgnoreCase("chart")) { ChartExcelRequest request = JsonUtil.parseObject(exportTask.getParams(), ChartExcelRequest.class); exportCenterDownLoadManage.startViewTask(exportTask, request); @@ -377,15 +377,19 @@ public class ExportCenterManage implements BaseExportApi { iterator.remove(); } } - FileUtils.deleteDirectoryRecursively(resolveExportTaskDirectory(id)); + FileUtils.deleteDirectoryRecursively(resolveExportBasePath(), resolveExportTaskDirectory(id)); exportTaskMapper.deleteById(id); } + private Path resolveExportBasePath() { + return Paths.get(exportData_path).toAbsolutePath().normalize(); + } + private Path resolveExportTaskDirectory(String taskId) { if (StringUtils.isBlank(taskId) || !StringUtils.isNumeric(taskId)) { DEException.throwException("任务不存在"); } - Path exportBasePath = Paths.get(exportData_path).toAbsolutePath().normalize(); + Path exportBasePath = resolveExportBasePath(); Path exportTaskPath = exportBasePath.resolve(taskId).normalize(); if (!exportTaskPath.startsWith(exportBasePath)) { DEException.throwException("Invalid export task path"); diff --git a/sdk/common/src/main/java/io/dataease/utils/FileUtils.java b/sdk/common/src/main/java/io/dataease/utils/FileUtils.java index 5692cc9822..f6868c8610 100644 --- a/sdk/common/src/main/java/io/dataease/utils/FileUtils.java +++ b/sdk/common/src/main/java/io/dataease/utils/FileUtils.java @@ -10,9 +10,10 @@ import org.springframework.web.multipart.MultipartFile; import java.io.*; import java.nio.channels.FileChannel; import java.nio.file.Files; -import java.nio.file.LinkOption; import java.nio.file.Path; -import java.nio.file.Paths; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.FileVisitResult; +import java.nio.file.attribute.BasicFileAttributes; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; @@ -295,32 +296,52 @@ public class FileUtils { } - public static boolean deleteDirectoryRecursively(String directoryPath) { - Assert.hasText(directoryPath, "Directory path must not be blank"); - return deleteDirectoryRecursively(Paths.get(directoryPath)); - } - - public static boolean deleteDirectoryRecursively(Path directory) { + public static boolean deleteDirectoryRecursively(Path baseDirectory, Path directory) { + Assert.notNull(baseDirectory, "Base directory must not be null"); Assert.notNull(directory, "Directory path must not be null"); + Path normalizedBaseDirectory = baseDirectory.toAbsolutePath().normalize(); Path normalizedDirectory = directory.toAbsolutePath().normalize(); - if (Files.notExists(normalizedDirectory, LinkOption.NOFOLLOW_LINKS)) { + if (!normalizedDirectory.startsWith(normalizedBaseDirectory)) { + DEException.throwException("Invalid directory path"); + } + if (Files.notExists(normalizedDirectory)) { return true; } - File[] files = normalizedDirectory.toFile().listFiles(); - if (files == null) { - return normalizedDirectory.toFile().delete(); + return deleteDirectoryRecursivelyInternal(normalizedBaseDirectory, normalizedDirectory); + } + + private static boolean deleteDirectoryRecursivelyInternal(Path baseDirectory, Path directory) { + try { + Files.walkFileTree(directory, new SimpleFileVisitor<>() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + validateChildPath(baseDirectory, file); + Files.deleteIfExists(file); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { + if (exc != null) { + throw exc; + } + validateChildPath(baseDirectory, dir); + Files.deleteIfExists(dir); + return FileVisitResult.CONTINUE; + } + }); + return true; + } catch (IOException e) { + LogUtil.error(e.getMessage(), e); + DEException.throwException(e); } - for (File file : files) { - Path child = file.toPath().toAbsolutePath().normalize(); - if (!child.startsWith(normalizedDirectory)) { - DEException.throwException("Invalid directory path"); - } - if (Files.isDirectory(child, LinkOption.NOFOLLOW_LINKS)) { - deleteDirectoryRecursively(child); - } else { - file.delete(); - } + return false; + } + + private static void validateChildPath(Path baseDirectory, Path childPath) { + Path normalizedChildPath = childPath.toAbsolutePath().normalize(); + if (!normalizedChildPath.startsWith(baseDirectory)) { + DEException.throwException("Invalid directory path"); } - return normalizedDirectory.toFile().delete(); } }