filter zip name

This commit is contained in:
2023-05-27 19:14:13 +08:00
parent 21a17dd9d7
commit 8f0ed03117
3 changed files with 38 additions and 3 deletions

View File

@@ -1,7 +1,7 @@
import { join } from "std/path/mod.ts";
import { Uint8ArrayReader, ZipWriter } from "zipjs/index.js";
import { EhDb } from "../db.ts";
import { addZero, asyncForEach } from "../utils.ts";
import { addZero, asyncForEach, filterFilename } from "../utils.ts";
import { Config } from "../config.ts";
import { Task } from "../task.ts";
@@ -22,7 +22,7 @@ export async function export_zip(
const g = db.get_gmeta_by_gid(gid);
if (!g) throw Error("Gallery not found in database.");
const output = ecfg.output === undefined
? join(cfg.base, g.title + ".zip")
? join(cfg.base, filterFilename(g.title + ".zip"))
: ecfg.output;
const f = await Deno.open(output, {
create: true,

View File

@@ -1,4 +1,5 @@
import { exists, existsSync } from "std/fs/exists.ts";
import { extname } from "std/path/mod.ts";
import { initParser } from "deno_dom/deno-dom-wasm-noinit.ts";
export function sleep(time: number): Promise<undefined> {
@@ -111,3 +112,25 @@ export function addZero(n: string | number, len: number) {
while (s.length < len) s = "0" + s;
return s;
}
export function filterFilename(p: string, maxLength = 256) {
// strip control chars
p = p.replace(/\p{C}/gu, "");
// normalize newline
p = p.replace(/[\n\r]/g, "");
p = p.replace(/\p{Zl}/gu, "");
p = p.replace(/\p{Zp}/gu, "");
// normalize space
p = p.replace(/\p{Zs}/gu, " ");
p = p.replace(/[\\/]/g, "_");
if (Deno.build.os == "windows") {
p = p.replace(/[:\*\?\"<>\|]/g, "_");
} else if (Deno.build.os == "linux") {
p = p.replace(/[!\$\"]/g, "_");
}
if (p.length > maxLength) {
const ext = extname(p);
return p.slice(0, maxLength - ext.length) + ext;
}
return p;
}

View File

@@ -3,6 +3,7 @@ import { check_running } from "./pid_check.ts";
import {
asyncFilter,
asyncForEach,
filterFilename,
promiseState,
PromiseStatus,
sleep,
@@ -49,7 +50,7 @@ Deno.test("asyncFilter_test", async () => {
await Promise.allSettled(e);
});
Deno.test("asyncForEach", async () => {
Deno.test("asyncForEach_test", async () => {
const e = [new Promise<number>((res) => setTimeout(() => res(100), 100))];
const t = { test: 2 };
await asyncForEach(e, async function (e) {
@@ -57,3 +58,14 @@ Deno.test("asyncForEach", async () => {
await e;
}, t);
});
Deno.test("filterFilename_test", () => {
assertEquals(filterFilename("abcdef.ts", 5), "ab.ts");
assertEquals(filterFilename("\x00df\t\r.ts"), "df.ts");
assertEquals(filterFilename("a\u200bd.ts"), "ad.ts");
assertEquals(filterFilename("中文.ts"), "中文.ts");
assertEquals(filterFilename("d\\s/.ts"), "d_s_.ts");
if (Deno.build.os == "windows") {
assertEquals(filterFilename("d|?ad.ts"), "d__ad.ts");
}
});