Add proper escaping for .desktop entries

' in a pack name would be entered as 'Foo'\''blah' rather than
"Foo'blah" as the spec would require.

Assisted-by: OpenAI ChatGPT
Signed-off-by: Dominic Monroe <dominic@dominic.io>
This commit is contained in:
Dominic Monroe 2026-05-24 16:55:55 +01:00
parent f67a670bcf
commit 84c5a0778f

View file

@ -913,6 +913,26 @@ QString quoteArgs(const QStringList& args, const QString& wrap, const QString& e
return result;
}
QString quoteDesktopExecArg(QString arg)
{
arg.replace("\\", "\\\\\\\\");
arg.replace("$", "\\\\$");
arg.replace("\"", "\\\"");
arg.replace("`", "\\`");
arg.replace("%", "%%");
return QStringLiteral("\"") + arg + QStringLiteral("\"");
}
QString quoteDesktopExecArgs(const QStringList& args)
{
QStringList result;
result.reserve(args.size());
for (auto arg : args) {
result.append(quoteDesktopExecArg(arg));
}
return result.join(' ');
}
// Cross-platform Shortcut creation
QString createShortcut(QString destination, QString target, QStringList args, QString name, QString icon)
{
@ -1007,12 +1027,13 @@ QString createShortcut(QString destination, QString target, QStringList args, QS
}
QTextStream stream(&f);
auto argstring = quoteArgs(args, "'", "'\\''");
args.prepend(target);
auto argstring = quoteDesktopExecArgs(args);
stream << "[Desktop Entry]" << "\n";
stream << "Type=Application" << "\n";
stream << "Categories=Game;ActionGame;AdventureGame;Simulation" << "\n";
stream << "Exec=\"" << target.toLocal8Bit() << "\" " << argstring.toLocal8Bit() << "\n";
stream << "Exec=" << argstring.toLocal8Bit() << "\n";
stream << "Name=" << name.toLocal8Bit() << "\n";
if (!icon.isEmpty()) {
stream << "Icon=" << icon.toLocal8Bit() << "\n";