Fix crash on invalid image data.

This commit is contained in:
John Preston 2020-05-30 22:37:03 +04:00
parent 4695ebae6e
commit 423ea5b499
6 changed files with 33 additions and 11 deletions

View File

@ -320,6 +320,9 @@ namespace App {
} }
QImage readImage(QByteArray data, QByteArray *format, bool opaque, bool *animated) { QImage readImage(QByteArray data, QByteArray *format, bool opaque, bool *animated) {
if (data.isEmpty()) {
return QImage();
}
QByteArray tmpFormat; QByteArray tmpFormat;
QImage result; QImage result;
QBuffer buffer(&data); QBuffer buffer(&data);

View File

@ -177,6 +177,9 @@ public:
[[nodiscard]] QByteArray inlineThumbnailBytes() const { [[nodiscard]] QByteArray inlineThumbnailBytes() const {
return _inlineThumbnailBytes; return _inlineThumbnailBytes;
} }
void clearInlineThumbnailBytes() {
_inlineThumbnailBytes = QByteArray();
}
[[nodiscard]] Storage::Cache::Key goodThumbnailCacheKey() const; [[nodiscard]] Storage::Cache::Key goodThumbnailCacheKey() const;
[[nodiscard]] bool goodThumbnailChecked() const; [[nodiscard]] bool goodThumbnailChecked() const;

View File

@ -171,9 +171,14 @@ void DocumentMedia::setGoodThumbnail(QImage thumbnail) {
Image *DocumentMedia::thumbnailInline() const { Image *DocumentMedia::thumbnailInline() const {
if (!_inlineThumbnail) { if (!_inlineThumbnail) {
auto image = Images::FromInlineBytes(_owner->inlineThumbnailBytes()); const auto bytes = _owner->inlineThumbnailBytes();
if (!image.isNull()) { if (!bytes.isEmpty()) {
_inlineThumbnail = std::make_unique<Image>(std::move(image)); auto image = Images::FromInlineBytes(bytes);
if (image.isNull()) {
_owner->clearInlineThumbnailBytes();
} else {
_inlineThumbnail = std::make_unique<Image>(std::move(image));
}
} }
} }
return _inlineThumbnail.get(); return _inlineThumbnail.get();
@ -360,10 +365,11 @@ Image *DocumentMedia::getStickerSmall() {
} }
void DocumentMedia::checkStickerLarge(not_null<FileLoader*> loader) { void DocumentMedia::checkStickerLarge(not_null<FileLoader*> loader) {
if (_owner->sticker() if (_sticker || !_owner->sticker()) {
&& !_sticker return;
&& !loader->imageData().isNull()) { }
_sticker = std::make_unique<Image>(loader->imageData()); if (auto image = loader->imageData(); !image.isNull()) {
_sticker = std::make_unique<Image>(std::move(image));
} }
} }

View File

@ -88,6 +88,9 @@ public:
[[nodiscard]] QByteArray inlineThumbnailBytes() const { [[nodiscard]] QByteArray inlineThumbnailBytes() const {
return _inlineThumbnailBytes; return _inlineThumbnailBytes;
} }
void clearInlineThumbnailBytes() {
_inlineThumbnailBytes = QByteArray();
}
void load( void load(
Data::FileOrigin origin, Data::FileOrigin origin,

View File

@ -34,9 +34,14 @@ not_null<PhotoData*> PhotoMedia::owner() const {
Image *PhotoMedia::thumbnailInline() const { Image *PhotoMedia::thumbnailInline() const {
if (!_inlineThumbnail) { if (!_inlineThumbnail) {
auto image = Images::FromInlineBytes(_owner->inlineThumbnailBytes()); const auto bytes = _owner->inlineThumbnailBytes();
if (!image.isNull()) { if (!bytes.isEmpty()) {
_inlineThumbnail = std::make_unique<Image>(std::move(image)); auto image = Images::FromInlineBytes(bytes);
if (image.isNull()) {
_owner->clearInlineThumbnailBytes();
} else {
_inlineThumbnail = std::make_unique<Image>(std::move(image));
}
} }
} }
return _inlineThumbnail.get(); return _inlineThumbnail.get();

View File

@ -112,7 +112,9 @@ Image::Image(const QString &path) : Image(ReadContent(path)) {
Image::Image(const QByteArray &content) : Image(ReadImage(content)) { Image::Image(const QByteArray &content) : Image(ReadImage(content)) {
} }
Image::Image(QImage &&data) : _data(std::move(data)) { Image::Image(QImage &&data)
: _data(data.isNull() ? Empty()->original() : std::move(data)) {
Expects(!_data.isNull());
} }
not_null<Image*> Image::Empty() { not_null<Image*> Image::Empty() {