diff --git a/src/pkg/utils/utils.test.ts b/src/pkg/utils/utils.test.ts index 0fb5d0cf7..bb93716b9 100644 --- a/src/pkg/utils/utils.test.ts +++ b/src/pkg/utils/utils.test.ts @@ -427,7 +427,6 @@ describe.concurrent("checkSilenceUpdate", () => { describe.concurrent("cleanFileName", () => { it.concurrent("should replace illegal characters with dashes", () => { - expect(cleanFileName("file/name")).toBe("file-name"); expect(cleanFileName("file\\name")).toBe("file-name"); expect(cleanFileName("file:name")).toBe("file-name"); expect(cleanFileName("file*name")).toBe("file-name"); @@ -443,6 +442,7 @@ describe.concurrent("cleanFileName", () => { it.concurrent("should handle valid filename", () => { expect(cleanFileName("valid_file.txt")).toBe("valid_file.txt"); + expect(cleanFileName("file/name.txt")).toBe("file/name.txt"); }); }); diff --git a/src/pkg/utils/utils.ts b/src/pkg/utils/utils.ts index 350913a6b..3694abd0f 100644 --- a/src/pkg/utils/utils.ts +++ b/src/pkg/utils/utils.ts @@ -396,8 +396,14 @@ export function toCamelCase(key: SystemConfigKey) { } export function cleanFileName(name: string): string { - // eslint-disable-next-line no-control-regex, no-useless-escape - return name.replace(/[\x00-\x1F\\\/:*?"<>|]+/g, "-").trim(); + // https://github.com/Tampermonkey/tampermonkey/issues/2413 + // https://developer.chrome.com/docs/extensions/reference/api/downloads#type-DownloadOptions + // A file path relative to the Downloads directory to contain the downloaded file, possibly containing subdirectories. + // Absolute paths, empty paths, and paths containing back-references ".." will cause an error. + let n = name; + // eslint-disable-next-line no-control-regex + n = n.replace(/[\x00-\x1F\\:*?"<>|]+/g, "-"); + return n.replace(/\.\.+/g, "-").trim(); } export const sourceMapTo = (scriptName: string) => {