2
0
mirror of https://github.com/telegramdesktop/tdesktop synced 2025-08-31 06:26:18 +00:00

Fix crash in DocumentData destructor.

Keep AuthSession pointer in DocumentData for loader destruction.
This commit is contained in:
John Preston
2018-01-27 12:21:57 +03:00
parent 63c1212ef1
commit a858ab5d0b
8 changed files with 187 additions and 180 deletions

View File

@@ -9,6 +9,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_types.h"
class AuthSession;
inline uint64 mediaMix32To64(int32 a, int32 b) {
return (uint64(*reinterpret_cast<uint32*>(&a)) << 32)
| uint64(*reinterpret_cast<uint32*>(&b));
@@ -42,10 +44,7 @@ struct DocumentAdditionalData {
struct StickerData : public DocumentAdditionalData {
ImagePtr img;
QString alt;
MTPInputStickerSet set = MTP_inputStickerSetEmpty();
bool setInstalled() const;
StorageImageLocation loc; // doc thumb location
};
@@ -72,17 +71,9 @@ class Document;
class DocumentData {
public:
static DocumentData *create(DocumentId id);
static DocumentData *create(
DocumentId id,
int32 dc,
uint64 accessHash,
int32 version,
const QVector<MTPDocumentAttribute> &attributes);
static DocumentData *create(
DocumentId id,
const QString &url,
const QVector<MTPDocumentAttribute> &attributes);
DocumentData(DocumentId id, not_null<AuthSession*> session);
not_null<AuthSession*> session() const;
void setattributes(
const QVector<MTPDocumentAttribute> &attributes);
@@ -130,44 +121,14 @@ public:
void forget();
ImagePtr makeReplyPreview();
StickerData *sticker() {
return (type == StickerDocument)
? static_cast<StickerData*>(_additional.get())
: nullptr;
}
void checkSticker() {
StickerData *s = sticker();
if (!s) return;
StickerData *sticker() const;
void checkSticker();
bool isStickerSetInstalled() const;
SongData *song();
const SongData *song() const;
VoiceData *voice();
const VoiceData *voice() const;
automaticLoad(nullptr);
if (s->img->isNull() && loaded()) {
if (_data.isEmpty()) {
const FileLocation &loc(location(true));
if (loc.accessEnable()) {
s->img = ImagePtr(loc.name());
loc.accessDisable();
}
} else {
s->img = ImagePtr(_data);
}
}
}
SongData *song() {
return isSong()
? static_cast<SongData*>(_additional.get())
: nullptr;
}
const SongData *song() const {
return const_cast<DocumentData*>(this)->song();
}
VoiceData *voice() {
return isVoiceMessage()
? static_cast<VoiceData*>(_additional.get())
: nullptr;
}
const VoiceData *voice() const {
return const_cast<DocumentData*>(this)->voice();
}
bool isVoiceMessage() const;
bool isVideoMessage() const;
bool isSong() const;
@@ -187,20 +148,9 @@ public:
bool setRemoteVersion(int32 version); // Returns true if version has changed.
void setRemoteLocation(int32 dc, uint64 access);
void setContentUrl(const QString &url);
bool hasRemoteLocation() const {
return (_dc != 0 && _access != 0);
}
bool isValid() const {
return hasRemoteLocation() || !_url.isEmpty();
}
MTPInputDocument mtpInput() const {
if (_access) {
return MTP_inputDocument(
MTP_long(id),
MTP_long(_access));
}
return MTP_inputDocumentEmpty();
}
bool hasRemoteLocation() const;
bool isValid() const;
MTPInputDocument mtpInput() const;
// When we have some client-side generated document
// (for example for displaying an external inline bot result)
@@ -208,18 +158,18 @@ public:
// to (this) received from the server "same" document.
void collectLocalData(DocumentData *local);
QString filename() const {
return _filename;
}
QString mimeString() const {
return _mimeString;
}
bool hasMimeType(QLatin1String mime) const {
return !_mimeString.compare(mime, Qt::CaseInsensitive);
}
void setMimeString(const QString &mime) {
_mimeString = mime;
}
QString filename() const;
QString mimeString() const;
bool hasMimeType(QLatin1String mime) const;
void setMimeString(const QString &mime);
MediaKey mediaKey() const;
static QString ComposeNameString(
const QString &filename,
const QString &songTitle,
const QString &songPerformer);
QString composeNameString() const;
~DocumentData();
@@ -234,44 +184,12 @@ public:
std::unique_ptr<Data::UploadState> uploadingData;
int32 md5[8];
MediaKey mediaKey() const {
return ::mediaKey(locationType(), _dc, id, _version);
}
static QString ComposeNameString(
const QString &filename,
const QString &songTitle,
const QString &songPerformer);
QString composeNameString() const {
if (auto songData = song()) {
return ComposeNameString(
_filename,
songData->title,
songData->performer);
}
return ComposeNameString(_filename, QString(), QString());
}
private:
DocumentData(
DocumentId id,
int32 dc,
uint64 accessHash,
int32 version,
const QString &url,
const QVector<MTPDocumentAttribute> &attributes);
friend class Serialize::Document;
LocationType locationType() const {
return isVoiceMessage()
? AudioFileLocation
: isVideoFile()
? VideoFileLocation
: DocumentFileLocation;
}
LocationType locationType() const;
void destroyLoaderDelayed(mtpFileLoader *newValue = nullptr) const;
// Two types of location: from MTProto by dc+access+version or from web by url
int32 _dc = 0;
@@ -281,6 +199,8 @@ private:
QString _filename;
QString _mimeString;
not_null<AuthSession*> _session;
FileLocation _location;
QByteArray _data;
std::unique_ptr<DocumentAdditionalData> _additional;
@@ -290,9 +210,6 @@ private:
FullMsgId _actionOnLoadMsgId;
mutable FileLoader *_loader = nullptr;
void destroyLoaderDelayed(
mtpFileLoader *newValue = nullptr) const;
};
VoiceWaveform documentWaveformDecode(const QByteArray &encoded5bit);