Sanitize file names taken from server metadata (closes #9)
check / check (push) Successful in 37s

A file title or album name decrypted from server data could name a path
outside the chosen directory (`../../.ssh/authorized_keys`). One module,
src/filename.ts, now makes such names safe for `quak get`/`get-thumb`
without `--out`, downloadFile/downloadThumbnail without outPath, and the
backup and metadata backup trees. Originals-cache extensions are limited to
letters and digits. A user-supplied path is still used as is. decryptFile
reads a missing or non-string title as "" and rejects metadata that is not
a JSON object.

Model: opus-5-5
This commit was merged in pull request #78.
This commit is contained in:
2026-09-23 02:04:31 +02:00
parent fe952d3e62
commit 3871d6228e
15 changed files with 381 additions and 44 deletions
+2 -4
View File
@@ -4,6 +4,7 @@ import * as jpeg from "jpeg-js";
import exifReader from "exif-reader";
import type { Client } from "./client.js";
import type { Library, Photo } from "./library/index.js";
import { sanitizeFileName } from "./filename.js";
import { fetchMLData } from "./mldata-fetch.js";
import type { EnteFile } from "./model/types.js";
@@ -14,9 +15,6 @@ export interface MetadataBackupOptions {
onProgress?: ProgressCallback;
}
const sanitizePath = (name: string): string =>
name.replace(/[/\\:*?"<>|]/g, "_").replace(/^\.+/, "_");
// Extract the raw EXIF APP1 segment from JPEG bytes. Returns the EXIF
// data buffer (starting after the APP1 length field, at the "Exif\0\0"
// header) or undefined if no APP1 marker is found.
@@ -151,7 +149,7 @@ export const runMetadataBackup = async (
const col = lib.getCollection(album.collectionID);
if (!col) continue;
const dirName = `${col.id}-${sanitizePath(col.name || "unnamed")}`;
const dirName = `${col.id}-${sanitizeFileName(col.name, "unnamed")}`;
const colDir = join(outDir, "collections", dirName);
mkdirSync(colDir, { recursive: true });