On Mon, Aug 31, 2026 at 09:54:20PM +0200, Pavel Sanda wrote:
> The first batch of patches tries to sanitize runCommand() calls.
...
> +/// Split a shell-style command string into space-separated tokens, with
> +/// double-quoted tokens copied verbatim. Used to migrate string-form
> +/// invocations to the argv-form of Systemcall::startscriptArgv without
> +/// going through a shell. NOT a full shell parser: no $VAR / $() /
> +/// backslash escape handling, no single-quote handling.
> +std::vector<std::string> splitCommandTokens(std::string const & cmd);

Definition of this function was part of later patch, better to fold here.

Pavel
diff --git a/src/support/Systemcall.cpp b/src/support/Systemcall.cpp
index c882ed5344..7ca8c3e280 100644
--- a/src/support/Systemcall.cpp
+++ b/src/support/Systemcall.cpp
@@ -788,6 +788,40 @@ void SystemcallPrivate::killProcess(QProcess * p)
 	}
 }
 
+vector<string> splitCommandTokens(string const & cmd)
+{
+	vector<string> argv;
+	size_t i = 0;
+	while (i < cmd.size()) {
+
+		// skip to the next token
+		while (i < cmd.size() && (cmd[i] == ' ' || cmd[i] == '\t'))
+			++i;
+		if (i >= cmd.size())
+			break;
+
+		string tok;
+
+		// token quoted
+		if (cmd[i] == '"') {
+			++i;
+			while (i < cmd.size() && cmd[i] != '"')
+				tok += cmd[i++];
+			if (i < cmd.size())
+				++i;	// step over closing quote
+
+		// token unquoted
+		} else {
+			while (i < cmd.size() && cmd[i] != ' ' && cmd[i] != '\t')
+				tok += cmd[i++];
+		}
+		if (!tok.empty())
+			argv.push_back(tok);
+	}
+	return argv;
+}
+
+
 } // namespace support
 } // namespace lyx
 
diff --git a/src/support/Systemcall.h b/src/support/Systemcall.h
index c8d73053ea..bff1c11afc 100644
--- a/src/support/Systemcall.h
+++ b/src/support/Systemcall.h
@@ -94,8 +94,19 @@ public:
 /// Split a shell-style command string into space-separated tokens, with
 /// double-quoted tokens copied verbatim. Used to migrate string-form
 /// invocations to the argv-form of Systemcall::startscriptArgv without
-/// going through a shell. NOT a full shell parser: no $VAR / $() /
-/// backslash escape handling, no single-quote handling.
+/// going through a shell.
+///
+/// Not a full shell parser. Space and tab separate, empty tokens are
+/// dropped, and there is no handling of $VAR / $(), backslash escapes or
+/// single quotes.
+/// A double quote is only a delimiter at the start of a token: inside a
+/// token it is copied as an ordinary character, unlike a shell, which would
+/// remove it. An unterminated quote is not an error - it is dropped and
+/// the remainder of the string becomes a single token.
+///
+/// Used to split only strings LyX produced itself (python) or that come from
+/// user preferences. Document-supplied values must be appended as their own
+/// argv elements, never parsed here.
 std::vector<std::string> splitCommandTokens(std::string const & cmd);
 
 
-- 
lyx-devel mailing list
[email protected]
https://lists.lyx.org/mailman/listinfo/lyx-devel

Reply via email to