Platform: unix - avoid modifying the environment

Modifying the process environment can cause crashes in application code
that accesses the environment via non-qt functions on worker threads.
When launching a process, we can avoid modifying the environment of the
caller by using QProcess with setEnvironment. The codepaths without
QProcess support is still prone to these issues and could potentially be
improved via execve

Task-number: QTBUG-129222
Change-Id: I4e2d93abaa0e392b341041faaae0ffd11e225bcb
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
(cherry picked from commit 673400679dca23840174c9882cea5b796b52b2f7)
bb10
Tim Blechmann 2024-12-17 12:59:24 +08:00
parent 2097519b3e
commit 686d994a44
1 changed files with 16 additions and 7 deletions

View File

@ -134,27 +134,36 @@ static inline bool detectWebBrowser(const QByteArray &desktop,
static inline bool launch(const QString &launcher, const QUrl &url,
const QString &xdgActivationToken)
{
if (!xdgActivationToken.isEmpty()) {
qputenv("XDG_ACTIVATION_TOKEN", xdgActivationToken.toUtf8());
}
const QString command = launcher + u' ' + QLatin1StringView(url.toEncoded());
if (debug)
qDebug("Launching %s", qPrintable(command));
#if !QT_CONFIG(process)
if (!xdgActivationToken.isEmpty())
qputenv("XDG_ACTIVATION_TOKEN", xdgActivationToken.toUtf8());
const bool ok = ::system(qPrintable(command + " &"_L1));
#else
if (!xdgActivationToken.isEmpty())
qunsetenv("XDG_ACTIVATION_TOKEN");
# else
QStringList args = QProcess::splitCommand(command);
bool ok = false;
if (!args.isEmpty()) {
QString program = args.takeFirst();
ok = QProcess::startDetached(program, args);
QProcess process;
process.setProgram(program);
process.setArguments(args);
if (!xdgActivationToken.isEmpty()) {
auto env = QProcessEnvironment::systemEnvironment();
env.insert(u"XDG_ACTIVATION_TOKEN"_s, xdgActivationToken);
process.setEnvironment(env.toStringList());
}
ok = process.startDetached(nullptr);
}
#endif
# endif
if (!ok)
qWarning("Launch failed (%s)", qPrintable(command));
qunsetenv("XDG_ACTIVATION_TOKEN");
return ok;
}