Details
-
Bug
-
Resolution: Done
-
P1: Critical
-
5.6.2
-
None
-
QT 5.6.2 32 bits on Windows 10
Description
One of our customers has contacted us reporting a crash managing a XPM file (attached).
The code that crashes tries to save the image in JPG format to a QBuffer, setting a white background to not have the transparent pixels black in the final image.
Here is a minimal example code that crashes with the attached image.
#include <QImageReader> #include <QImage> #include <QPainter> #include <QBuffer> #include <QByteArray> #include <iostream> int main(int argc, char *argv[]) { QImageReader imageReader("image.xpm"); QImage result = imageReader.read(); if (result.isNull()) { std::cerr << "Image not found" << std::endl; return 0; } QImage finalImage(result.size(), QImage::Format_RGB32); finalImage.fill(QColor(Qt::white).rgb()); QPainter painter(&finalImage); painter.drawImage(0, 0, result); QByteArray ba; QBuffer buffer(&ba); buffer.open(QIODevice::WriteOnly); finalImage.save(&buffer, "JPG", 85); return 0; }
This is the stacktrace:
1 convertIndexedToARGB32PM qdrawhelper.cpp 411 0x588763f2 2 fetchUntransformed qdrawhelper.cpp 1428 0x5887baa6 3 blend_untransformed_generic qdrawhelper.cpp 4165 0x5888e4ac 4 qBlendTexture qdrawhelper.cpp 5494 0x588756cc 5 fillRect_normalized qpaintengine_raster.cpp 1441 0x588d268e 6 QRasterPaintEngine::drawImage qpaintengine_raster.cpp 2138 0x588c8ccc 7 QPainter::drawImage qpainter.cpp 5363 0x588e6ad7 8 QPainter::drawImage qpainter.h 852 0x585b16ed 9 main main.cpp 24 0x27151d 10 invoke_main exe_common.inl 64 0x27238e 11 __scrt_common_main_seh exe_common.inl 255 0x2721da 12 __scrt_common_main exe_common.inl 300 0x27206d 13 mainCRTStartup exe_main.cpp 17 0x2723a8 14 BaseThreadInitThunk KERNEL32 0x74b362c4 15 RtlSubscribeWnfStateChangeNotification ntdll 0x77b40fd9 16 RtlSubscribeWnfStateChangeNotification ntdll 0x77b40fa4
The crash happens here:
qdrawhelper.cpp:407
// To convert in place, let 'dest' and 'src' be the same. static const uint *QT_FASTCALL convertIndexedToARGB32PM(uint *buffer, const uint *src, int count, const QPixelLayout *, const QRgb *clut) { for (int i = 0; i < count; ++i) buffer[i] = qPremultiply(clut[src[i]]); /// <------ crash! return buffer; }
According to the debugger, "clut" is NULL.
In the calling function, it's clear that that parameter can be NULL.
qdrawhelper.cpp:1421
static const uint *QT_FASTCALL fetchUntransformed(uint *buffer, const Operator *, const QSpanData *data, int y, int x, int length) { const QPixelLayout *layout = &qPixelLayouts[data->texture.format]; const uint *ptr = qFetchPixels[layout->bpp](buffer, data->texture.scanLine(y), x, length); const QRgb *clut = data->texture.colorTable ? data->texture.colorTable->constData() : 0; return layout->convertToARGB32PM(buffer, ptr, length, layout, clut); }
So, probably, there should be a protection in the calling function (fetchUntransformed) or in convertToARGB32PM to prevent the crash.
Thank you!