From 31dbe2278ec014cd02a8dde3322731ef8476b933 Mon Sep 17 00:00:00 2001 From: John Preston Date: Wed, 20 Mar 2019 14:17:40 +0400 Subject: [PATCH] Fix possible crash in local file streaming. Cache file size instead of requesting it from file system each time. --- .../streaming/media_streaming_loader_local.cpp | 17 ++++++++++++++--- .../streaming/media_streaming_loader_local.h | 3 ++- .../media/streaming/media_streaming_reader.cpp | 4 +++- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/Telegram/SourceFiles/media/streaming/media_streaming_loader_local.cpp b/Telegram/SourceFiles/media/streaming/media_streaming_loader_local.cpp index 47c727471..a4319d7dd 100644 --- a/Telegram/SourceFiles/media/streaming/media_streaming_loader_local.cpp +++ b/Telegram/SourceFiles/media/streaming/media_streaming_loader_local.cpp @@ -11,12 +11,23 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace Media { namespace Streaming { +namespace { + +// This is the maximum file size in Telegram API. +constexpr auto kMaxFileSize = 3000 * 512 * 1024; + +int ValidateLocalSize(int64 size) { + return (size > 0 && size <= kMaxFileSize) ? int(size) : 0; +} + +} // namespace LoaderLocal::LoaderLocal(std::unique_ptr device) -: _device(std::move(device)) { +: _device(std::move(device)) +, _size(ValidateLocalSize(_device->size())) { Expects(_device != nullptr); - if (!_device->open(QIODevice::ReadOnly)) { + if (!_size || !_device->open(QIODevice::ReadOnly)) { fail(); } } @@ -26,7 +37,7 @@ std::optional LoaderLocal::baseCacheKey() const { } int LoaderLocal::size() const { - return _device->size(); + return _size; } void LoaderLocal::load(int offset) { diff --git a/Telegram/SourceFiles/media/streaming/media_streaming_loader_local.h b/Telegram/SourceFiles/media/streaming/media_streaming_loader_local.h index 6a856d468..04be7271d 100644 --- a/Telegram/SourceFiles/media/streaming/media_streaming_loader_local.h +++ b/Telegram/SourceFiles/media/streaming/media_streaming_loader_local.h @@ -35,7 +35,8 @@ public: private: void fail(); - std::unique_ptr _device; + const std::unique_ptr _device; + const int _size = 0; rpl::event_stream _parts; }; diff --git a/Telegram/SourceFiles/media/streaming/media_streaming_reader.cpp b/Telegram/SourceFiles/media/streaming/media_streaming_reader.cpp index 2b8195654..640c35bfa 100644 --- a/Telegram/SourceFiles/media/streaming/media_streaming_reader.cpp +++ b/Telegram/SourceFiles/media/streaming/media_streaming_reader.cpp @@ -568,7 +568,9 @@ Reader::SerializedSlice Reader::Slices::serializeAndUnloadUnused() { } Reader::SerializedSlice Reader::Slices::serializeAndUnloadSlice( - int sliceNumber) { + int sliceNumber) { + Expects(_headerMode != HeaderMode::Unknown); + Expects(_headerMode != HeaderMode::NoCache); Expects(sliceNumber >= 0 && sliceNumber <= _data.size()); if (isGoodHeader() && (sliceNumber == 1)) {