Fix possible crash in local file streaming.

Cache file size instead of requesting it from file system each time.
This commit is contained in:
John Preston 2019-03-20 14:17:40 +04:00
parent 9ed064b7fc
commit 31dbe2278e
3 changed files with 19 additions and 5 deletions

View File

@ -11,12 +11,23 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Media { namespace Media {
namespace Streaming { 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<QIODevice> device) LoaderLocal::LoaderLocal(std::unique_ptr<QIODevice> device)
: _device(std::move(device)) { : _device(std::move(device))
, _size(ValidateLocalSize(_device->size())) {
Expects(_device != nullptr); Expects(_device != nullptr);
if (!_device->open(QIODevice::ReadOnly)) { if (!_size || !_device->open(QIODevice::ReadOnly)) {
fail(); fail();
} }
} }
@ -26,7 +37,7 @@ std::optional<Storage::Cache::Key> LoaderLocal::baseCacheKey() const {
} }
int LoaderLocal::size() const { int LoaderLocal::size() const {
return _device->size(); return _size;
} }
void LoaderLocal::load(int offset) { void LoaderLocal::load(int offset) {

View File

@ -35,7 +35,8 @@ public:
private: private:
void fail(); void fail();
std::unique_ptr<QIODevice> _device; const std::unique_ptr<QIODevice> _device;
const int _size = 0;
rpl::event_stream<LoadedPart> _parts; rpl::event_stream<LoadedPart> _parts;
}; };

View File

@ -568,7 +568,9 @@ Reader::SerializedSlice Reader::Slices::serializeAndUnloadUnused() {
} }
Reader::SerializedSlice Reader::Slices::serializeAndUnloadSlice( Reader::SerializedSlice Reader::Slices::serializeAndUnloadSlice(
int sliceNumber) { int sliceNumber) {
Expects(_headerMode != HeaderMode::Unknown);
Expects(_headerMode != HeaderMode::NoCache);
Expects(sliceNumber >= 0 && sliceNumber <= _data.size()); Expects(sliceNumber >= 0 && sliceNumber <= _data.size());
if (isGoodHeader() && (sliceNumber == 1)) { if (isGoodHeader() && (sliceNumber == 1)) {