From d9e93fb5cc8ea82b88302a42821b57ce4a4f0a93 Mon Sep 17 00:00:00 2001 From: John Preston Date: Mon, 17 Jun 2019 13:54:00 +0200 Subject: [PATCH] Fix possible crash in auth session destruction. --- Telegram/SourceFiles/apiwrap.cpp | 4 ++++ Telegram/SourceFiles/apiwrap.h | 4 +++- Telegram/SourceFiles/storage/file_download.cpp | 17 ++++++++++++----- Telegram/SourceFiles/storage/file_download.h | 3 +++ 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index 08d387b17c..e0a05586cc 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -248,6 +248,10 @@ ApiWrap::ApiWrap(not_null session) }); } +AuthSession &ApiWrap::session() const { + return *_session; +} + void ApiWrap::setupSupportMode() { if (!_session->supportMode()) { return; diff --git a/Telegram/SourceFiles/apiwrap.h b/Telegram/SourceFiles/apiwrap.h index 2db4513ec9..84bbf63c08 100644 --- a/Telegram/SourceFiles/apiwrap.h +++ b/Telegram/SourceFiles/apiwrap.h @@ -99,7 +99,9 @@ public: bool operator!=(const BlockedUsersSlice &other) const; }; - ApiWrap(not_null session); + explicit ApiWrap(not_null session); + + AuthSession &session() const; void applyUpdates(const MTPUpdates &updates, uint64 sentMessageRandomId = 0); void applyNotifySettings( diff --git a/Telegram/SourceFiles/storage/file_download.cpp b/Telegram/SourceFiles/storage/file_download.cpp index 550b21b8c3..3f6d009b7b 100644 --- a/Telegram/SourceFiles/storage/file_download.cpp +++ b/Telegram/SourceFiles/storage/file_download.cpp @@ -171,6 +171,10 @@ FileLoader::FileLoader( Expects(!_filename.isEmpty() || (_size <= Storage::kMaxFileInMemory)); } +AuthSession &FileLoader::session() const { + return _downloader->api().session(); +} + void FileLoader::finishWithBytes(const QByteArray &data) { _data = data; _localStatus = LocalStatus::Loaded; @@ -411,7 +415,7 @@ void FileLoader::loadLocal(const Storage::Cache::Key &key) { std::move(image)); }); }; - Auth().data().cache().get(key, [=, callback = std::move(done)]( + session().data().cache().get(key, [=, callback = std::move(done)]( QByteArray &&value) mutable { if (readImage) { crl::async([ @@ -478,6 +482,7 @@ void FileLoader::cancel(bool fail) { removeFromQueue(); const auto queue = _queue; + const auto sessionGuard = &session(); const auto weak = make_weak(this); if (fail) { emit failed(this, started); @@ -488,7 +493,9 @@ void FileLoader::cancel(bool fail) { _filename = QString(); _file.setFileName(_filename); } - LoadNextFromQueue(queue); + + // Current cancel() call could be made from ~AuthSession(). + crl::on_main(sessionGuard, [=] { LoadNextFromQueue(queue); }); } void FileLoader::startLoading() { @@ -596,7 +603,7 @@ bool FileLoader::finalizeResult() { } if ((_toCache == LoadToCacheAsWell) && (_data.size() <= Storage::kMaxFileInMemory)) { - Auth().data().cache().put( + session().data().cache().put( cacheKey(), Storage::Cache::Database::TaggedValue( base::duplicate(_data), @@ -775,7 +782,7 @@ mtpRequestId mtpFileLoader::sendRequest(const RequestData &requestData) { }, [&](const StorageFileLocation &location) { return MTP::send( MTPupload_GetFile( - location.tl(Auth().userId()), + location.tl(session().userId()), MTP_int(offset), MTP_int(limit)), rpcDone(&mtpFileLoader::normalPartLoaded), @@ -1053,7 +1060,7 @@ bool mtpFileLoader::normalPartFailed( } if (error.code() == 400 && error.type().startsWith(qstr("FILE_REFERENCE_"))) { - Auth().api().refreshFileReference( + session().api().refreshFileReference( _origin, this, requestId, diff --git a/Telegram/SourceFiles/storage/file_download.h b/Telegram/SourceFiles/storage/file_download.h index 400edff696..76a6afc39b 100644 --- a/Telegram/SourceFiles/storage/file_download.h +++ b/Telegram/SourceFiles/storage/file_download.h @@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_file_origin.h" class ApiWrap; +class AuthSession; namespace Storage { namespace Cache { @@ -107,6 +108,8 @@ public: bool autoLoading, uint8 cacheTag); + AuthSession &session() const; + bool finished() const { return _finished; }