[LyX/2.5.x] Hardening case 00i+00h - shell-safe document basename via makeLatexName

Richard Kimberly Heck <[email protected]>
Newsgroups gmane.editors.lyx.cvs
Message-ID <[email protected]>
commit 61c5e4326008278157e09ba28b9291d3975599ea
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 af24b90713..a4986f1ba2 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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.