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