On Tue, Sep 01, 2026 at 08:35:31PM +0200, Pavel Sanda wrote:
> On Mon, Aug 31, 2026 at 09:54:20PM +0200, Pavel Sanda wrote:
> > The first batch of patches tries to sanitize runCommand() calls.
> 
> The next one uses new startscriptArgv to close kpsewhich hole
> in a less fragile way.

The 4th-one kicks runCommand from lyx2lyx invocation and replaces
former quoting hotfix.

Mostly mechanical rewrite with new argv API.
Pavel
>From 01e25f41b5f44ad7559777297a3d6a5a7b01cb1b Mon Sep 17 00:00:00 2001
From: Pavel Sanda <[email protected]>
Date: Fri, 11 Sep 2026 22:12:22 +0200
Subject: [PATCH 07/11] Route the lyx2lyx invocation through argv form

Retires runCommand() & sh_quote() guard (fragile to get right across
platforms to avoid command injection) from lyx2lyx conversion chain.

Missing python interpreter now reports before spawning rather than
failing later.

Tier 01 DiD / argv 03b: argv-form lyx2lyx
                        re-closes 00b (f3a89bd504) structurally

Assisted-by: Claude Opus 5
---
 src/Buffer.cpp | 41 +++++++++++++++++++----------------------
 1 file changed, 19 insertions(+), 22 deletions(-)

diff --git a/src/Buffer.cpp b/src/Buffer.cpp
index 5b339b4837..60e23b9f50 100644
--- a/src/Buffer.cpp
+++ b/src/Buffer.cpp
@@ -1413,28 +1413,26 @@ Buffer::ReadStatus Buffer::convertLyXFormat(FileName const & fn,
 
 	// Run lyx2lyx:
 	//   $python$ "$lyx2lyx$" -t $LYX_FORMAT$ -o "$tempfile$" "$filetoread$"
+	//
+	// fn is user-controlled string, we need argv form of invocation
+	vector<string> argv = os::pythonArgvForm();
+	if (argv.empty()) {
+		LYXERR0("No python interpreter found, cannot run lyx2lyx.");
+		return LyX2LyXNotFound;
+	}
+	string const program = argv.front();
+	argv.erase(argv.begin());
+	argv.push_back(lyx2lyx.toFilesystemEncoding());
+	argv.push_back("-t");
+	argv.push_back(convert<string>(LYX_FORMAT));
+	argv.push_back("-o");
+	argv.push_back(tmpfile.toSafeFilesystemEncoding());
+	argv.push_back(fn.toSafeFilesystemEncoding());
 
-	// guard against command expansion in filename strings on linux,
-	// keep " on windows
-	auto sh_quote = [](string const & s) -> string {
-#ifdef _WIN32
-		return quoteName(s);
-#else
-		return '\'' + subst(s, "'", "'\\''") + '\'';
-#endif
-	};
-	ostringstream command;
-	command << os::python()
-		<< ' ' << sh_quote(lyx2lyx.toFilesystemEncoding())
-		<< " -t " << convert<string>(LYX_FORMAT)
-		<< " -o " << sh_quote(tmpfile.toSafeFilesystemEncoding())
-		<< ' ' << sh_quote(fn.toSafeFilesystemEncoding());
-	string const command_str = command.str();
-
-	LYXERR(Debug::INFO, "Running '" << command_str << '\'');
-
-	cmd_ret const ret = runCommand(command_str);
-	if (!ret.valid) {
+	LYXERR(Debug::INFO, "Running lyx2lyx on '" << fn.absFileName() << '\'');
+
+	Systemcall one;
+	if (one.startscriptArgv(program, argv) != Systemcall::OK) {
 		if (from_format < LYX_FORMAT) {
 			Alert::error(_("Conversion script failed"),
 				bformat(_("%1$s is from an older version"
-- 
2.39.5

-- 
lyx-devel mailing list
[email protected]
https://lists.lyx.org/mailman/listinfo/lyx-devel

Reply via email to