Fix incomplete traversal of clipboard data when an image is present resulting in Not an Image error (#5156)

This commit is contained in:
hemirt 2024-02-24 13:52:35 +01:00 committed by GitHub
parent df2b5f94f4
commit 66910507dc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 48 additions and 43 deletions

View file

@ -87,6 +87,7 @@
- Bugfix: Reply contexts now use the color of the replied-to message. (#5145) - Bugfix: Reply contexts now use the color of the replied-to message. (#5145)
- Bugfix: Fixed top-level window getting stuck after opening settings. (#5161, #5166) - Bugfix: Fixed top-level window getting stuck after opening settings. (#5161, #5166)
- Bugfix: Fixed link info not updating without moving the cursor. (#5178) - Bugfix: Fixed link info not updating without moving the cursor. (#5178)
- Bugfix: Fixed an upload sometimes failing when copying an image from a browser if it contained extra properties. (#5156)
- Bugfix: Fixed tooltips getting out of bounds when loading images. (#5186) - Bugfix: Fixed tooltips getting out of bounds when loading images. (#5186)
- Dev: Run miniaudio in a separate thread, and simplify it to not manage the device ourselves. There's a chance the simplification is a bad idea. (#4978) - Dev: Run miniaudio in a separate thread, and simplify it to not manage the device ourselves. There's a chance the simplification is a bad idea. (#4978)
- Dev: Change clang-format from v14 to v16. (#4929) - Dev: Change clang-format from v14 to v16. (#4929)

View file

@ -238,7 +238,7 @@ void ImageUploader::handleSuccessfulUpload(const NetworkResult &result,
} }
else else
{ {
QTimer::singleShot(UPLOAD_DELAY, [channel, &textEdit, this]() { QTimer::singleShot(UPLOAD_DELAY, [channel, textEdit, this]() {
this->sendImageUploadRequest(this->uploadQueue_.front(), channel, this->sendImageUploadRequest(this->uploadQueue_.front(), channel,
textEdit); textEdit);
this->uploadQueue_.pop(); this->uploadQueue_.pop();
@ -259,8 +259,11 @@ void ImageUploader::upload(const QMimeData *source, ChannelPtr channel,
} }
channel->addMessage(makeSystemMessage(QString("Started upload..."))); channel->addMessage(makeSystemMessage(QString("Started upload...")));
if (source->hasUrls()) auto tryUploadFromUrls = [&]() -> bool {
if (!source->hasUrls())
{ {
return false;
}
auto mimeDb = QMimeDatabase(); auto mimeDb = QMimeDatabase();
// This path gets chosen when files are copied from a file manager, like explorer.exe, caja. // This path gets chosen when files are copied from a file manager, like explorer.exe, caja.
// Each entry in source->urls() is a QUrl pointing to a file that was copied. // Each entry in source->urls() is a QUrl pointing to a file that was copied.
@ -277,8 +280,7 @@ void ImageUploader::upload(const QMimeData *source, ChannelPtr channel,
{ {
channel->addMessage( channel->addMessage(
makeSystemMessage(QString("Couldn't load image :("))); makeSystemMessage(QString("Couldn't load image :(")));
this->uploadMutex_.unlock(); return false;
return;
} }
auto imageData = convertToPng(img); auto imageData = convertToPng(img);
@ -293,8 +295,7 @@ void ImageUploader::upload(const QMimeData *source, ChannelPtr channel,
QString("Cannot upload file: %1. Couldn't convert " QString("Cannot upload file: %1. Couldn't convert "
"image to png.") "image to png.")
.arg(localPath))); .arg(localPath)));
this->uploadMutex_.unlock(); return false;
return;
} }
} }
else if (mime.inherits("image/gif")) else if (mime.inherits("image/gif"))
@ -307,21 +308,12 @@ void ImageUploader::upload(const QMimeData *source, ChannelPtr channel,
{ {
channel->addMessage( channel->addMessage(
makeSystemMessage(QString("Failed to open file. :("))); makeSystemMessage(QString("Failed to open file. :(")));
this->uploadMutex_.unlock(); return false;
return;
} }
// file.readAll() => might be a bit big but it /should/ work
RawImageData data = {file.readAll(), "gif", localPath}; RawImageData data = {file.readAll(), "gif", localPath};
this->uploadQueue_.push(data); this->uploadQueue_.push(data);
file.close(); file.close();
// file.readAll() => might be a bit big but it /should/ work
}
else
{
channel->addMessage(makeSystemMessage(
QString("Cannot upload file: %1. Not an image.")
.arg(localPath)));
this->uploadMutex_.unlock();
return;
} }
} }
if (!this->uploadQueue_.empty()) if (!this->uploadQueue_.empty())
@ -329,41 +321,53 @@ void ImageUploader::upload(const QMimeData *source, ChannelPtr channel,
this->sendImageUploadRequest(this->uploadQueue_.front(), channel, this->sendImageUploadRequest(this->uploadQueue_.front(), channel,
outputTextEdit); outputTextEdit);
this->uploadQueue_.pop(); this->uploadQueue_.pop();
return true;
} }
} return false;
else if (source->hasFormat("image/png")) };
auto tryUploadDirectly = [&]() -> bool {
if (source->hasFormat("image/png"))
{ {
// the path to file is not present every time, thus the filePath is empty // the path to file is not present every time, thus the filePath is empty
this->sendImageUploadRequest({source->data("image/png"), "png", ""}, this->sendImageUploadRequest({source->data("image/png"), "png", ""},
channel, outputTextEdit); channel, outputTextEdit);
return true;
} }
else if (source->hasFormat("image/jpeg")) if (source->hasFormat("image/jpeg"))
{ {
this->sendImageUploadRequest({source->data("image/jpeg"), "jpeg", ""}, this->sendImageUploadRequest(
channel, outputTextEdit); {source->data("image/jpeg"), "jpeg", ""}, channel,
outputTextEdit);
return true;
} }
else if (source->hasFormat("image/gif")) if (source->hasFormat("image/gif"))
{ {
this->sendImageUploadRequest({source->data("image/gif"), "gif", ""}, this->sendImageUploadRequest({source->data("image/gif"), "gif", ""},
channel, outputTextEdit); channel, outputTextEdit);
return true;
} }
// not PNG, try loading it into QImage and save it to a PNG.
else
{ // not PNG, try loading it into QImage and save it to a PNG.
auto image = qvariant_cast<QImage>(source->imageData()); auto image = qvariant_cast<QImage>(source->imageData());
auto imageData = convertToPng(image); auto imageData = convertToPng(image);
if (imageData) if (imageData)
{ {
sendImageUploadRequest({*imageData, "png", ""}, channel, sendImageUploadRequest({*imageData, "png", ""}, channel,
outputTextEdit); outputTextEdit);
return true;
} }
else // No direct upload happenned
{
channel->addMessage(makeSystemMessage( channel->addMessage(makeSystemMessage(
QString("Cannot upload file, failed to convert to png."))); QString("Cannot upload file, failed to convert to png.")));
return false;
};
if (!tryUploadFromUrls() && !tryUploadDirectly())
{
channel->addMessage(
makeSystemMessage(QString("Cannot upload file from clipboard.")));
this->uploadMutex_.unlock(); this->uploadMutex_.unlock();
} }
} }
}
} // namespace chatterino } // namespace chatterino