commit 8478add4c0bacf0e67dee8446363ef266da8146d
Author: Pavel Sanda <[email protected]>
Date: Sat Jun 13 23:18:52 2026 +0200
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 | 29 ++++++++++++++++++++++++++---
1 file changed, 26 insertions(+), 3 deletions(-)
diff --git a/src/support/filetools.cpp b/src/support/filetools.cpp
index 823ff78728..705ec8d365 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)
--
lyx-cvs mailing list
[email protected]
https://lists.lyx.org/mailman/listinfo/lyx-cvs