From dcf70b2847553a364a6ad92c3551d121f316c307 Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 6 Mar 2018 19:04:47 +0300 Subject: [PATCH] Add ".download" for .lnk and .scf file names. This is a workaround for some windows shell vulnerabilities. See http://www.defensecode.com/whitepapers/ Stealing-Windows-Credentials-Using-Google-Chrome.pdf --- Telegram/SourceFiles/data/data_document.cpp | 37 +++++++++++++++++++-- Telegram/SourceFiles/data/data_document.h | 2 +- Telegram/SourceFiles/mediaview.cpp | 2 +- 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/Telegram/SourceFiles/data/data_document.cpp b/Telegram/SourceFiles/data/data_document.cpp index de8b611c9..e35e5ba77 100644 --- a/Telegram/SourceFiles/data/data_document.cpp +++ b/Telegram/SourceFiles/data/data_document.cpp @@ -65,7 +65,13 @@ bool fileIsImage(const QString &name, const QString &mime) { return false; } -QString saveFileName(const QString &title, const QString &filter, const QString &prefix, QString name, bool savingAs, const QDir &dir) { +QString FileNameUnsafe( + const QString &title, + const QString &filter, + const QString &prefix, + QString name, + bool savingAs, + const QDir &dir) { #ifdef Q_OS_WIN name = name.replace(QRegularExpression(qsl("[\\\\\\/\\:\\*\\?\\\"\\<\\>\\|]")), qsl("_")); #elif defined Q_OS_MAC @@ -152,6 +158,33 @@ QString saveFileName(const QString &title, const QString &filter, const QString return name; } +QString FileNameForSave( + const QString &title, + const QString &filter, + const QString &prefix, + QString name, + bool savingAs, + const QDir &dir) { + const auto result = FileNameUnsafe( + title, + filter, + prefix, + name, + savingAs, + dir); +#ifdef Q_OS_WIN + const auto lower = result.trimmed().toLower(); + const auto kBadExtensions = { qstr(".lnk"), qstr(".scf") }; + const auto kMaskExtension = qsl(".download"); + for (const auto extension : kBadExtensions) { + if (lower.endsWith(extension)) { + return result + kMaskExtension; + } + } +#endif // Q_OS_WIN + return result; +} + QString documentSaveFilename(const DocumentData *data, bool forceSavingAs = false, const QString already = QString(), const QDir &dir = QDir()) { auto alreadySavingFilename = data->loadingFilePath(); if (!alreadySavingFilename.isEmpty()) { @@ -195,7 +228,7 @@ QString documentSaveFilename(const DocumentData *data, bool forceSavingAs = fals prefix = qsl("doc"); } - return saveFileName(caption, filter, prefix, name, forceSavingAs, dir); + return FileNameForSave(caption, filter, prefix, name, forceSavingAs, dir); } void DocumentOpenClickHandler::doOpen( diff --git a/Telegram/SourceFiles/data/data_document.h b/Telegram/SourceFiles/data/data_document.h index f49806414..bede848fa 100644 --- a/Telegram/SourceFiles/data/data_document.h +++ b/Telegram/SourceFiles/data/data_document.h @@ -288,7 +288,7 @@ protected: }; -QString saveFileName( +QString FileNameForSave( const QString &title, const QString &filter, const QString &prefix, diff --git a/Telegram/SourceFiles/mediaview.cpp b/Telegram/SourceFiles/mediaview.cpp index fd45e0b4a..e73d1089a 100644 --- a/Telegram/SourceFiles/mediaview.cpp +++ b/Telegram/SourceFiles/mediaview.cpp @@ -821,7 +821,7 @@ void MediaView::onSaveAs() { } psBringToBack(this); - file = saveFileName(lang(lng_save_file), filter, qsl("doc"), name, true, alreadyDir); + file = FileNameForSave(lang(lng_save_file), filter, qsl("doc"), name, true, alreadyDir); psShowOverAll(this); if (!file.isEmpty() && file != location.name()) { if (_doc->data().isEmpty()) {