fix: 标题是否合法增加对斜杠、反斜杠、冒号的判断

This commit is contained in:
Ted 2025-09-04 04:30:44 +08:00
parent 5c3a4e4b1b
commit 649cc89a22
4 changed files with 92 additions and 9 deletions

View file

@ -5,6 +5,7 @@ import TagInput from "src/components/TagInput";
import BanyanPlugin from "src/main";
import { i18n } from "src/utils/i18n";
import { useCombineStore } from "src/store";
import { legalFileName } from "src/utils/utils";
interface AddNoteViewProps {
app: App;
@ -121,7 +122,7 @@ const AddNoteView: React.FC<AddNoteViewProps> = ({ app, plugin, onAdd }) => {
onChange={(e) => {
const newTitle = e.target.value;
setTitle(newTitle);
setIsTitleInvalid(newTitle.length > 0 && !plugin.fileUtils.legalFileName(newTitle));
setIsTitleInvalid(newTitle.length > 0 && !legalFileName(newTitle));
}}
onKeyDown={(e) => {
// 防止用户在标题输入换行符
@ -151,7 +152,7 @@ const AddNoteView: React.FC<AddNoteViewProps> = ({ app, plugin, onAdd }) => {
if (body.trim().length === 0 && tags.length === 0 && _title.length === 0) return;
// 检查标题合法性
if (_title && !plugin.fileUtils.legalFileName(_title)) {
if (_title && !legalFileName(_title)) {
new Notice(i18n.t('illegal_title_chars'));
return;
}

View file

@ -4,6 +4,7 @@ import { createFileInfo, FileInfo, generateFileId } from "src/models/FileInfo";
import { TagFilter, isOKWithTagFilter } from "src/models/TagFilter";
import { i18n } from "./i18n";
import moment from "moment";
import { legalFileName } from "./utils";
const PlaceholderFileName = "banyan_editor_placeholder.md";
@ -82,10 +83,6 @@ export class FileUtils {
return format;
}
public legalFileName(fileName: string) {
return !/[\[\]#^|]/.test(fileName);
}
private sanitizeFileName(rawTitle: string) {
// 移除/替换常见非法字符,保留与插件一致的校验
let name = rawTitle.trim();
@ -95,7 +92,7 @@ export class FileUtils {
.replace(/[\n\r\t]/g, " ")
.replace(/\s+/g, " ")
.trim();
if (!this.legalFileName(name)) {
if (!legalFileName(name)) {
name = name.replace(/[\[\]#^|]/g, "-");
}
// 避免空文件名
@ -128,11 +125,11 @@ export class FileUtils {
let fileName: string = "";
// 如果有标题且标题合法,使用标题作为文件名
if (title && title.trim() && this.legalFileName(title.trim())) {
if (title && title.trim() && legalFileName(title.trim())) {
fileName = `${title.trim()}.md`;
} else if (formatStr) {
const name = `${moment().format(formatStr)}.md`;
if (this.legalFileName(name)) {
if (legalFileName(name)) {
fileName = name;
console.log("formated file name:", fileName);
} else {

4
src/utils/utils.ts Normal file
View file

@ -0,0 +1,4 @@
export function legalFileName(fileName: string) {
return !/[\[\]#^|\\/:]/.test(fileName);
}

81
test/FileUtils.test.ts Normal file
View file

@ -0,0 +1,81 @@
import { legalFileName } from "../src/utils/utils";
// 直接测试 legalFileName 方法,避免复杂的依赖
describe('legalFileName', () => {
test('应该接受合法的文件名', () => {
expect(legalFileName('valid-file-name')).toBe(true);
expect(legalFileName('my_note')).toBe(true);
expect(legalFileName('2023-12-25')).toBe(true);
expect(legalFileName('中文文件名')).toBe(true);
expect(legalFileName('file123')).toBe(true);
});
test('应该拒绝包含方括号的文件名', () => {
expect(legalFileName('file[1]')).toBe(false);
expect(legalFileName('[important]')).toBe(false);
expect(legalFileName('note]test')).toBe(false);
});
test('应该拒绝包含井号的文件名', () => {
expect(legalFileName('file#1')).toBe(false);
expect(legalFileName('#important')).toBe(false);
expect(legalFileName('note#test')).toBe(false);
});
test('应该拒绝包含脱字符的文件名', () => {
expect(legalFileName('file^1')).toBe(false);
expect(legalFileName('^important')).toBe(false);
expect(legalFileName('note^test')).toBe(false);
});
test('应该拒绝包含竖线的文件名', () => {
expect(legalFileName('file|1')).toBe(false);
expect(legalFileName('|important')).toBe(false);
expect(legalFileName('note|test')).toBe(false);
});
test('应该拒绝包含反斜杠的文件名', () => {
expect(legalFileName('file\\1')).toBe(false);
expect(legalFileName('\\important')).toBe(false);
expect(legalFileName('note\\test')).toBe(false);
});
test('应该拒绝包含正斜杠的文件名', () => {
expect(legalFileName('file/1')).toBe(false);
expect(legalFileName('/important')).toBe(false);
expect(legalFileName('note/test')).toBe(false);
});
test('应该拒绝包含冒号的文件名', () => {
expect(legalFileName('file:1')).toBe(false);
expect(legalFileName(':important')).toBe(false);
expect(legalFileName('note:test')).toBe(false);
});
test('应该拒绝包含多个非法字符的文件名', () => {
expect(legalFileName('file[1]#test')).toBe(false);
expect(legalFileName('note|test:file')).toBe(false);
expect(legalFileName('path/to\\file')).toBe(false);
expect(legalFileName('file^test#important')).toBe(false);
});
test('应该处理空字符串', () => {
expect(legalFileName('')).toBe(true);
});
test('应该处理只包含非法字符的字符串', () => {
expect(legalFileName('[')).toBe(false);
expect(legalFileName(']')).toBe(false);
expect(legalFileName('#')).toBe(false);
expect(legalFileName('^')).toBe(false);
expect(legalFileName('|')).toBe(false);
expect(legalFileName('\\')).toBe(false);
expect(legalFileName('/')).toBe(false);
expect(legalFileName(':')).toBe(false);
});
test('应该处理包含所有非法字符的字符串', () => {
expect(legalFileName('[]#^|\\/:')).toBe(false);
});
});