From 456a949d0129a945c1b2c46a26f3253a977167d6 Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 4 Apr 2019 00:05:29 +0400 Subject: [PATCH] Fix working with document thumbnails. --- Telegram/SourceFiles/storage/localstorage.cpp | 11 ++++++++++- .../SourceFiles/storage/serialize_document.cpp | 16 ++++++++-------- Telegram/SourceFiles/ui/image/image_location.cpp | 16 ++++++++-------- Telegram/SourceFiles/ui/image/image_location.h | 3 +++ 4 files changed, 29 insertions(+), 17 deletions(-) diff --git a/Telegram/SourceFiles/storage/localstorage.cpp b/Telegram/SourceFiles/storage/localstorage.cpp index 5e9750a59..398d5c662 100644 --- a/Telegram/SourceFiles/storage/localstorage.cpp +++ b/Telegram/SourceFiles/storage/localstorage.cpp @@ -4009,6 +4009,11 @@ void readSavedGifs() { } auto &saved = Auth().data().savedGifsRef(); + const auto failed = [&] { + clearKey(_savedGifsKey); + _savedGifsKey = 0; + saved.clear(); + }; saved.clear(); quint32 cnt; @@ -4017,7 +4022,11 @@ void readSavedGifs() { OrderedSet read; for (uint32 i = 0; i < cnt; ++i) { auto document = Serialize::Document::readFromStream(gifs.version, gifs.stream); - if (!document || !document->isGifv()) continue; + if (!_checkStreamStatus(gifs.stream)) { + return failed(); + } else if (!document || !document->isGifv()) { + continue; + } if (read.contains(document->id)) continue; read.insert(document->id); diff --git a/Telegram/SourceFiles/storage/serialize_document.cpp b/Telegram/SourceFiles/storage/serialize_document.cpp index 86eef5dba..dff29af5f 100644 --- a/Telegram/SourceFiles/storage/serialize_document.cpp +++ b/Telegram/SourceFiles/storage/serialize_document.cpp @@ -131,14 +131,14 @@ DocumentData *Document::readFromStreamHelper(int streamAppVersion, QDataStream & } } - if ((!dc && !access) || !thumb) { + if ((!dc && !access) + || !thumb + || (thumb->valid() && !thumb->file().isDocumentThumbnail())) { + stream.setStatus(QDataStream::ReadCorruptData); + // We can't convert legacy thumbnail location to modern, because + // size letter ('s' or 'm') is lost, it was not saved in legacy. return nullptr; } - using LocationType = StorageFileLocation::Type; - const auto location = (thumb->valid() - && thumb->type() == LocationType::Legacy) - ? thumb->convertToModern(LocationType::Document, id, access) - : *thumb; return Auth().data().document( id, access, @@ -147,10 +147,10 @@ DocumentData *Document::readFromStreamHelper(int streamAppVersion, QDataStream & attributes, mime, ImagePtr(), - Images::Create(location), + Images::Create(*thumb), dc, size, - location); + *thumb); } DocumentData *Document::readStickerFromStream(int streamAppVersion, QDataStream &stream, const StickerSetInfo &info) { diff --git a/Telegram/SourceFiles/ui/image/image_location.cpp b/Telegram/SourceFiles/ui/image/image_location.cpp index 7c91b971c..8ae994e61 100644 --- a/Telegram/SourceFiles/ui/image/image_location.cpp +++ b/Telegram/SourceFiles/ui/image/image_location.cpp @@ -134,9 +134,7 @@ StorageFileLocation StorageFileLocation::convertToModern( uint64 id, uint64 accessHash) const { Expects(_type == Type::Legacy); - Expects(type == Type::Document - || type == Type::PeerPhoto - || type == Type::StickerSetThumb); + Expects(type == Type::PeerPhoto || type == Type::StickerSetThumb); auto result = *this; result._type = type; @@ -305,10 +303,15 @@ bool StorageFileLocation::valid() const { return false; } +bool StorageFileLocation::isDocumentThumbnail() const { + return (_type == Type::Document) && (_sizeLetter != 0); +} + Storage::Cache::Key StorageFileLocation::cacheKey() const { using Key = Storage::Cache::Key; - // Skip '1' and '2' for legacy document cache keys. + // Skip '1' for legacy document cache keys. + // Skip '2' because it is used for good (fullsize) document thumbnails. const auto shifted = ((uint64(_type) + 3) << 8); const auto sliced = uint64(_dcId) & 0xFFULL; switch (_type) { @@ -324,13 +327,10 @@ Storage::Cache::Key StorageFileLocation::cacheKey() const { return Key{ shifted | sliced, _id }; case Type::Document: - // Keep old cache keys for documents and document 'm' thumbnails. + // Keep old cache keys for documents. if (_sizeLetter == 0) { return Data::DocumentCacheKey(_dcId, _id); //return Key{ 0x100ULL | sliced, _id }; - } else if (_sizeLetter == uint8('m')) { - return Data::DocumentThumbCacheKey(_dcId, _id); - //return Key{ 0x200ULL | sliced, _id }; } [[fallthrough]]; case Type::Photo: diff --git a/Telegram/SourceFiles/ui/image/image_location.h b/Telegram/SourceFiles/ui/image/image_location.h index 814ff41b2..1527459be 100644 --- a/Telegram/SourceFiles/ui/image/image_location.h +++ b/Telegram/SourceFiles/ui/image/image_location.h @@ -86,6 +86,9 @@ public: [[nodiscard]] Storage::Cache::Key cacheKey() const; [[nodiscard]] Storage::Cache::Key bigFileBaseCacheKey() const; + // We have to allow checking this because of a serialization bug. + [[nodiscard]] bool isDocumentThumbnail() const; + [[nodiscard]] QByteArray fileReference() const; bool refreshFileReference(const Data::UpdatedFileReferences &updates); bool refreshFileReference(const QByteArray &data);