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

Reply via email to