diff --git a/src/main/java/run/halo/app/service/impl/BackupServiceImpl.java b/src/main/java/run/halo/app/service/impl/BackupServiceImpl.java index ed9a861ee..ef5957ff9 100644 --- a/src/main/java/run/halo/app/service/impl/BackupServiceImpl.java +++ b/src/main/java/run/halo/app/service/impl/BackupServiceImpl.java @@ -106,6 +106,7 @@ import run.halo.app.service.UserService; import run.halo.app.utils.DateTimeUtils; import run.halo.app.utils.DateUtils; import run.halo.app.utils.FileUtils; +import run.halo.app.utils.FilenameUtils; import run.halo.app.utils.HaloUtils; import run.halo.app.utils.JsonUtils; import run.halo.app.utils.VersionUtil; @@ -630,8 +631,9 @@ public class BackupServiceImpl implements BackupService { } content.append(postMarkdownVo.getOriginalContent()); try { + String filename = postMarkdownVo.getTitle() + "-" + postMarkdownVo.getSlug(); String markdownFileName = - postMarkdownVo.getTitle() + "-" + postMarkdownVo.getSlug() + ".md"; + FilenameUtils.sanitizeFilename(filename) + ".md"; Path markdownFilePath = Paths.get(markdownFileTempPathName, markdownFileName); if (!Files.exists(markdownFilePath.getParent())) { Files.createDirectories(markdownFilePath.getParent()); diff --git a/src/main/java/run/halo/app/utils/FilenameUtils.java b/src/main/java/run/halo/app/utils/FilenameUtils.java index f719b7a84..62432e748 100644 --- a/src/main/java/run/halo/app/utils/FilenameUtils.java +++ b/src/main/java/run/halo/app/utils/FilenameUtils.java @@ -3,9 +3,12 @@ package run.halo.app.utils; import java.io.File; import java.util.Arrays; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.apache.commons.lang3.StringUtils; import org.springframework.lang.NonNull; import org.springframework.util.Assert; +import run.halo.app.exception.FileOperationException; /** * Filename utilities. @@ -15,6 +18,14 @@ import org.springframework.util.Assert; */ public class FilenameUtils { + private static final Pattern FILENAME_RESERVED_CHARS_PATTERN = + Pattern.compile("[\\\\/:*?\"<>|.]"); + + private static final Pattern FILENAME_WIN_RESERVED_NAMES_PATTERN = + Pattern.compile("^(CON|PRM|AUX|NUL|COM[0-9]|LPT[0-9])$"); + + private static final int FILENAME_MAX_LENGTH = 200; + private FilenameUtils() { } @@ -104,4 +115,21 @@ public class FilenameUtils { return filename.substring(dotLastIndex + 1); } + /** + * @param filename filename + * @return sanitized filename, without any reserved character + */ + public static String sanitizeFilename(String filename) { + String sanitizedFilename = + FILENAME_RESERVED_CHARS_PATTERN.matcher(filename.trim()).replaceAll(""); + if (StringUtils.isEmpty(sanitizedFilename)) { + throw new FileOperationException("文件名不合法: " + filename); + } + Matcher matcher = FILENAME_WIN_RESERVED_NAMES_PATTERN.matcher(sanitizedFilename); + if (matcher.matches()) { + sanitizedFilename = sanitizedFilename + "_file"; + } + return sanitizedFilename.length() < FILENAME_MAX_LENGTH ? sanitizedFilename : + sanitizedFilename.substring(0, FILENAME_MAX_LENGTH).trim(); + } } diff --git a/src/test/java/run/halo/app/utils/FilenameUtilsTest.java b/src/test/java/run/halo/app/utils/FilenameUtilsTest.java index be60b1655..729f5f19a 100644 --- a/src/test/java/run/halo/app/utils/FilenameUtilsTest.java +++ b/src/test/java/run/halo/app/utils/FilenameUtilsTest.java @@ -1,8 +1,10 @@ package run.halo.app.utils; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; import org.junit.jupiter.api.Test; +import run.halo.app.exception.FileOperationException; /** * Filename utilities test. @@ -45,4 +47,67 @@ class FilenameUtilsTest { assertEquals("tar.gz", FilenameUtils.getExtension("he/ll/o.tar.gz")); assertEquals("tar.bz2", FilenameUtils.getExtension("he/ll/o.tar.bz2")); } + + @Test + public void fileNameWithReservedCharsWillBeReplaced() { + String filename1 = "abcde"; + String filteredFilename1 = FilenameUtils.sanitizeFilename(filename1); + assertEquals("abcde", filteredFilename1); + + String filename2 = "abcde|字符替换\\星号*大于>小于 FilenameUtils.sanitizeFilename(filename)); + assertEquals("文件名不合法: ?<>\\:*|...", exception.getMessage()); + } }