>From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Pavel Sanda Date: Sat, 13 Jun 2026 23:18:52 +0200 Subject: [PATCH] Hardening case 00i+00h - shell-safe document basename via makeLatexName makeLatexName() left shell metacharacters in the document's own filename (enters via Open/Import). That explodes in various converters (00h) and a subset is alive even inside double quoting (00i). Fires on export / View-PDF. Tier 00 fix: Tighten the keep-set to shell-safe alphanumerics + "+-._,@" Tier 04 fix for Unicode will land in master. Assisted-by: Claude Opus 4.7 --- src/support/filetools.cpp | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/src/support/filetools.cpp b/src/support/filetools.cpp index e0dc4e7654..f6c316f5a3 100644 --- a/src/support/filetools.cpp +++ b/src/support/filetools.cpp @@ -195,18 +195,41 @@ string const latex_path(string const & original_path, } -// Substitutes spaces with underscores in filename (and path) +// Sanitises filename for downstream conversion / helper consumers. +// +// CONTRACT: the basename of the returned FileName is shell-safe by +// construction. Every output byte is in the strict `keep` allow-list +// below (alphanumerics + "+-._,@"), so the result can flow into any +// downstream helper script in lib/scripts/ without re-escaping, even +// when the helper invokes a subprocess with shell=True and substitutes +// the filename unquoted. The function is idempotent: every output byte +// is in `keep`, so a second pass is a no-op. +// +// Bytes excluded from the keep-set are chosen to leave NO live POSIX +// shell metacharacter in any quoting context: +// - $ ` \ " special inside "..." +// - ; | & < > ( ) { } command separators / redirections / groups +// - * ? [ ] globs +// - ! ~ # ' history / tilde / comment / quote +// - whitespace (space, tab, newline) +// Bytes preserved beyond [A-Za-z0-9]: "+-._,@" - all POSIX shell-safe +// in every context and common in legitimate filenames. ':' is excluded +// because it is illegal on NTFS (Windows drive separator / Alternate +// Data Stream sigil), so preserving it would paper over a +// cross-platform portability bug rather than helping. +// +// Do NOT relax this set without auditing every consumer of +// Buffer::latexName() / makeLatexName() in lib/scripts/. FileName const makeLatexName(FileName const & file) { string name = file.onlyFileName(); string const path = file.onlyPath().absFileName() + "/"; - // ok so we scan through the string twice, but who cares. // FIXME: in Unicode time this will break for sure! There is // a non-latin world out there... string const keep = "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "@!'()*+,-./0123456789:;<=>?[]`|"; + "0123456789+-._,@"; string::size_type pos = 0; while ((pos = name.find_first_not_of(keep, pos)) != string::npos) -- 2.39.5