Fix escaping in linux launcher creating

This commit is contained in:
Ilya Fedin 2020-02-25 06:39:14 +04:00 committed by John Preston
parent 872e063501
commit 8b704f9bd7
5 changed files with 47 additions and 28 deletions

View File

@ -46,7 +46,7 @@ constexpr auto kDesktopFile = ":/misc/telegramdesktop.desktop"_cs;
constexpr auto kSnapLauncherDir = "/var/lib/snapd/desktop/applications/"_cs; constexpr auto kSnapLauncherDir = "/var/lib/snapd/desktop/applications/"_cs;
#ifndef TDESKTOP_DISABLE_DBUS_INTEGRATION #ifndef TDESKTOP_DISABLE_DBUS_INTEGRATION
void SandboxAutostart(bool autostart) { void SandboxAutostart(bool autostart, bool silent = false) {
QVariantMap options; QVariantMap options;
options["reason"] = tr::lng_settings_auto_start(tr::now); options["reason"] = tr::lng_settings_auto_start(tr::now);
options["autostart"] = autostart; options["autostart"] = autostart;
@ -62,11 +62,14 @@ void SandboxAutostart(bool autostart) {
qsl("org.freedesktop.portal.Background") qsl("org.freedesktop.portal.Background")
).call(qsl("RequestBackground"), QString(), options); ).call(qsl("RequestBackground"), QString(), options);
if (requestBackgroundReply.type() == QDBusMessage::ErrorMessage) { if (!silent) {
LOG(("Flatpak autostart error: %1") if (requestBackgroundReply.type() == QDBusMessage::ErrorMessage) {
.arg(requestBackgroundReply.errorMessage())); LOG(("Flatpak autostart error: %1")
} else if (requestBackgroundReply.type() != QDBusMessage::ReplyMessage) { .arg(requestBackgroundReply.errorMessage()));
LOG(("Flatpak autostart error: invalid reply")); } else if (requestBackgroundReply.type()
!= QDBusMessage::ReplyMessage) {
LOG(("Flatpak autostart error: invalid reply"));
}
} }
} }
#endif #endif
@ -120,7 +123,10 @@ void FallbackFontConfig() {
#endif // TDESKTOP_USE_FONT_CONFIG_FALLBACK #endif // TDESKTOP_USE_FONT_CONFIG_FALLBACK
} }
bool GenerateDesktopFile(const QString &targetPath, const QString &args) { bool GenerateDesktopFile(
const QString &targetPath,
const QString &args,
bool silent = false) {
DEBUG_LOG(("App Info: placing .desktop file to %1").arg(targetPath)); DEBUG_LOG(("App Info: placing .desktop file to %1").arg(targetPath));
if (!QDir(targetPath).exists()) QDir().mkpath(targetPath); if (!QDir(targetPath).exists()) QDir().mkpath(targetPath);
@ -142,7 +148,9 @@ bool GenerateDesktopFile(const QString &targetPath, const QString &args) {
fileText = s.readAll(); fileText = s.readAll();
source.close(); source.close();
} else { } else {
LOG(("App Error: Could not open '%1' for read").arg(sourceFile)); if (!silent) {
LOG(("App Error: Could not open '%1' for read").arg(sourceFile));
}
return false; return false;
} }
@ -150,21 +158,26 @@ bool GenerateDesktopFile(const QString &targetPath, const QString &args) {
if (target.open(QIODevice::WriteOnly)) { if (target.open(QIODevice::WriteOnly)) {
#ifdef DESKTOP_APP_USE_PACKAGED #ifdef DESKTOP_APP_USE_PACKAGED
fileText = fileText.replace( fileText = fileText.replace(
QRegularExpression(qsl("^Exec=(.*) -- %u$"), QRegularExpression(
qsl("^Exec=(.*) -- %u$"),
QRegularExpression::MultilineOption), QRegularExpression::MultilineOption),
qsl("Exec=\\1") qsl("Exec=\\1")
+ (args.isEmpty() ? QString() : ' ' + args)); + (args.isEmpty() ? QString() : ' ' + args));
#else #else
fileText = fileText.replace( fileText = fileText.replace(
QRegularExpression(qsl("^TryExec=.*$"), QRegularExpression(
qsl("^TryExec=.*$"),
QRegularExpression::MultilineOption), QRegularExpression::MultilineOption),
qsl("TryExec=") qsl("TryExec=")
+ EscapeShell(QFile::encodeName(cExeDir() + cExeName()))); + QFile::encodeName(cExeDir() + cExeName())
.replace('\\', qsl("\\\\")));
fileText = fileText.replace( fileText = fileText.replace(
QRegularExpression(qsl("^Exec=.*$"), QRegularExpression(
qsl("^Exec=.*$"),
QRegularExpression::MultilineOption), QRegularExpression::MultilineOption),
qsl("Exec=") qsl("Exec=")
+ EscapeShell(QFile::encodeName(cExeDir() + cExeName())) + EscapeShell(QFile::encodeName(cExeDir() + cExeName()))
.replace('\\', qsl("\\\\"))
+ (args.isEmpty() ? QString() : ' ' + args)); + (args.isEmpty() ? QString() : ' ' + args));
#endif #endif
target.write(fileText.toUtf8()); target.write(fileText.toUtf8());
@ -175,7 +188,9 @@ bool GenerateDesktopFile(const QString &targetPath, const QString &args) {
return true; return true;
} else { } else {
LOG(("App Error: Could not open '%1' for write").arg(targetFile)); if (!silent) {
LOG(("App Error: Could not open '%1' for write").arg(targetFile));
}
return false; return false;
} }
} }
@ -309,7 +324,6 @@ QString GetLauncherBasename() {
return possibleBasenames[0]; return possibleBasenames[0];
}(); }();
LOG(("Launcher filename is %1.desktop").arg(LauncherBasename));
return LauncherBasename; return LauncherBasename;
} }
@ -434,6 +448,7 @@ int psFixPrevious() {
namespace Platform { namespace Platform {
void start() { void start() {
LOG(("Launcher filename: %1").arg(GetLauncherFilename()));
FallbackFontConfig(); FallbackFontConfig();
#ifdef TDESKTOP_FORCE_GTK_FILE_DIALOG #ifdef TDESKTOP_FORCE_GTK_FILE_DIALOG
@ -456,12 +471,14 @@ void start() {
void finish() { void finish() {
} }
void RegisterCustomScheme() { void RegisterCustomScheme(bool force) {
#ifndef TDESKTOP_DISABLE_REGISTER_CUSTOM_SCHEME #ifndef TDESKTOP_DISABLE_REGISTER_CUSTOM_SCHEME
auto home = getHomeDir(); auto home = getHomeDir();
if (home.isEmpty() || cAlphaVersion() || cExeName().isEmpty()) if (home.isEmpty() || cExeName().isEmpty())
return; // don't update desktop file for alpha version return;
if (Core::UpdaterDisabled())
// don't update desktop file for alpha version or if updater is disabled
if ((cAlphaVersion() || Core::UpdaterDisabled()) && !force)
return; return;
const auto applicationsPath = QStandardPaths::writableLocation( const auto applicationsPath = QStandardPaths::writableLocation(
@ -473,7 +490,7 @@ void RegisterCustomScheme() {
const auto icons = const auto icons =
QStandardPaths::writableLocation( QStandardPaths::writableLocation(
QStandardPaths::GenericDataLocation) QStandardPaths::GenericDataLocation)
+ qsl("/icons/"); + qsl("/icons/");
if (!QDir(icons).exists()) QDir().mkpath(icons); if (!QDir(icons).exists()) QDir().mkpath(icons);
@ -487,7 +504,7 @@ void RegisterCustomScheme() {
} }
if (!iconExists) { if (!iconExists) {
if (QFile(qsl(":/gui/art/logo_256.png")).copy(icon)) { if (QFile(qsl(":/gui/art/logo_256.png")).copy(icon)) {
DEBUG_LOG(("App Info: Icon copied to 'tdata'")); DEBUG_LOG(("App Info: Icon copied to '%1'").arg(icon));
} }
} }
#endif // !TDESKTOP_DISABLE_DESKTOP_FILE_GENERATION #endif // !TDESKTOP_DISABLE_DESKTOP_FILE_GENERATION
@ -562,12 +579,12 @@ bool psShowOpenWithMenu(int x, int y, const QString &file) {
void psAutoStart(bool start, bool silent) { void psAutoStart(bool start, bool silent) {
auto home = getHomeDir(); auto home = getHomeDir();
if (home.isEmpty() || cAlphaVersion() || cExeName().isEmpty()) if (home.isEmpty() || cExeName().isEmpty())
return; return;
if (InSandbox()) { if (InSandbox()) {
#ifndef TDESKTOP_DISABLE_DBUS_INTEGRATION #ifndef TDESKTOP_DISABLE_DBUS_INTEGRATION
SandboxAutostart(start); SandboxAutostart(start, silent);
#endif #endif
} else { } else {
const auto autostart = [&] { const auto autostart = [&] {
@ -580,12 +597,12 @@ void psAutoStart(bool start, bool silent) {
} else { } else {
return QStandardPaths::writableLocation( return QStandardPaths::writableLocation(
QStandardPaths::GenericConfigLocation) QStandardPaths::GenericConfigLocation)
+ qsl("/autostart/"); + qsl("/autostart/");
} }
}(); }();
if (start) { if (start) {
GenerateDesktopFile(autostart, qsl("-autostart")); GenerateDesktopFile(autostart, qsl("-autostart"), silent);
} else { } else {
QFile::remove(autostart + GetLauncherFilename()); QFile::remove(autostart + GetLauncherFilename());
} }

View File

@ -136,7 +136,7 @@ void RemoveQuarantine(const QString &path) {
removexattr(local.data(), kQuarantineAttribute, 0); removexattr(local.data(), kQuarantineAttribute, 0);
} }
void RegisterCustomScheme() { void RegisterCustomScheme(bool force) {
#ifndef TDESKTOP_DISABLE_REGISTER_CUSTOM_SCHEME #ifndef TDESKTOP_DISABLE_REGISTER_CUSTOM_SCHEME
OSStatus result = LSSetDefaultHandlerForURLScheme(CFSTR("tg"), (CFStringRef)[[NSBundle mainBundle] bundleIdentifier]); OSStatus result = LSSetDefaultHandlerForURLScheme(CFSTR("tg"), (CFStringRef)[[NSBundle mainBundle] bundleIdentifier]);
DEBUG_LOG(("App Info: set default handler for 'tg' scheme result: %1").arg(result)); DEBUG_LOG(("App Info: set default handler for 'tg' scheme result: %1").arg(result));

View File

@ -28,7 +28,7 @@ enum class SystemSettingsType {
void SetWatchingMediaKeys(bool watching); void SetWatchingMediaKeys(bool watching);
void SetApplicationIcon(const QIcon &icon); void SetApplicationIcon(const QIcon &icon);
void RegisterCustomScheme(); void RegisterCustomScheme(bool force = false);
PermissionStatus GetPermissionStatus(PermissionType type); PermissionStatus GetPermissionStatus(PermissionType type);
void RequestPermission(PermissionType type, Fn<void(PermissionStatus)> resultCallback); void RequestPermission(PermissionType type, Fn<void(PermissionStatus)> resultCallback);
void OpenSystemSettingsForPermission(PermissionType type); void OpenSystemSettingsForPermission(PermissionType type);

View File

@ -404,7 +404,7 @@ namespace {
namespace Platform { namespace Platform {
void RegisterCustomScheme() { void RegisterCustomScheme(bool force) {
if (cExeName().isEmpty()) { if (cExeName().isEmpty()) {
return; return;
} }

View File

@ -112,10 +112,12 @@ auto GenerateCodes() {
} }
}); });
}); });
#ifndef TDESKTOP_DISABLE_REGISTER_CUSTOM_SCHEME
codes.emplace(qsl("registertg"), [](::Main::Session *session) { codes.emplace(qsl("registertg"), [](::Main::Session *session) {
Platform::RegisterCustomScheme(); Platform::RegisterCustomScheme(true);
Ui::Toast::Show("Forced custom scheme register."); Ui::Toast::Show("Forced custom scheme register.");
}); });
#endif // !TDESKTOP_DISABLE_REGISTER_CUSTOM_SCHEME
codes.emplace(qsl("export"), [](::Main::Session *session) { codes.emplace(qsl("export"), [](::Main::Session *session) {
session->data().startExport(); session->data().startExport();
}); });