Details
-
Bug
-
Resolution: Done
-
P2: Important
-
4.7.0, 4.8.3, 5.0.0 Beta 2
-
38726b19c0d89b135c1f92d931f64532f48e4597 (Qt 4.8), fde71d1ae7d6795a2eb56d7c422a1674058bac78 (Qt 5.0), 711773776ed324efce7f1ed227104da9c7e21e05 (Qt 5.0.2
Description
I've encountered problems with the following source-code line(s):
gui\image\QImage.cpp(1417): memcpy(image.scanLine, scanLine, bpl);
in
QImage QImage::copy(const QRect& r) const { [...] if (image.d->nbytes != d->nbytes) { int bpl = image.bytesPerLine(); int this_bpl = bytesPerLine(); //Q_ASSERT(bytesPerLine() >= bpl); for (int i = 0; i < height(); i++){ if(!IsBadReadPtr(scanLine(i), bpl)){ -> memcpy(image.scanLine(i), scanLine(i), bpl); }else{ qWarning("QImage::copy: memcpy(image.scanLine(i), scanLine(i), bpl); this_bpl=%d", this_bpl); } } } [...] }
If this->bytesPerLine() is smaller than image.bytesPerLine() memcpy() tries to read from an undefined memory region. This can result in an Access Viaolation.
One simple example is shown in the following CallStack:
QtGuirsd47.dll!QImage::copy(const QRect & r={...}) Zeile 1418 C++ QtGuirsd47.dll!QImage::detach() Zeile 1364 + 0x16 Bytes C++ QtGuirsd47.dll!QImage::scanLine(int i=0) Zeile 1860 C++ QtGuirsd47.dll!QRasterBuffer::colorizeBitmap(const QImage & image={...}, const QColor & color={...}) Zeile 4288 + 0xc Bytes C++ QtGuirsd47.dll!QSpanData::setup(const QBrush & brush={...}, int alpha=256, QPainter::CompositionMode compositionMode=CompositionMode_SourceOver) Zeile 5195 + 0x52 Bytes C++ QtGuirsd47.dll!QRasterPaintEngine::updateBrush(const QBrush & brush={...}) Zeile 858 C++ QtGuirsd47.dll!QRasterPaintEngine::ensureBrush(const QBrush & brush={...}) Zeile 272 C++ QtGuirsd47.dll!QRasterPaintEngine::ensureBrush() Zeile 273 + 0x1b Bytes C++ QtGuirsd47.dll!QRasterPaintEngine::drawRects(const QRect * rects=0x0035d470, int rectCount=1) Zeile 1513 C++ QtGuirsd47.dll!QPainter::drawRects(const QRect * rects=0x0035d470, int rectCount=1) Zeile 3552 C++ QtGuirsd47.dll!QPainter::drawRect(int x=16, int y=0, int w=250, int h=1) Zeile 649 C++ QtGuirsd47.dll!QWindowsStyle::drawPrimitive(QStyle::PrimitiveElement pe=PE_FrameFocusRect, const QStyleOption * opt=0x0035efb8, QPainter * p=0x003613d0, const QWidget * w=0x0ed06b08) Zeile 1529 C++ wgui11.dll!rsWinStyle::drawPrimitive(QStyle::PrimitiveElement pe=PE_FrameFocusRect, const QStyleOption * opt=0x0035efb8, QPainter * p=0x003613d0, const QWidget * w=0x0ed06b08) Zeile 1170 C++ QtGuirsd47.dll!QCommonStyle::drawControl(QStyle::ControlElement element=CE_RadioButton, const QStyleOption * opt=0x0036138c, QPainter * p=0x003613d0, const QWidget * widget=0x0ed06b08) Zeile 1322 C++ QtGuirsd47.dll!QWindowsStyle::drawControl(QStyle::ControlElement ce=CE_RadioButton, const QStyleOption * opt=0x0036138c, QPainter * p=0x003613d0, const QWidget * widget=0x0ed06b08) Zeile 2562 C++ wgui11.dll!rsWinStyle::drawControl(QStyle::ControlElement element=CE_RadioButton, const QStyleOption * opt=0x0036138c, QPainter * p=0x003613d0, const QWidget * w=0x0ed06b08) Zeile 3097 C++ QtGuirsd47.dll!QStylePainter::drawControl(QStyle::ControlElement ce=CE_RadioButton, const QStyleOption & opt={...}) Zeile 90 C++ > QtGuirsd47.dll!QRadioButton::paintEvent(QPaintEvent * __formal=0x00361c44) Zeile 245 C++ (rsWinStyle::drawControl() does nothing than to call QWindowsStyle::drawControl())
The QImage for painting the Radio-Button is fetched here with qt_imageForBrush(Dense4Pattern, true), wich only has 1 Byte per line, which was created in QBrushPatternImageCache with
QImage(qt_patternForBrush(style, 0), 8, 8, 1, QImage::Format_MonoLSB);
with only 1 byte per line.
Attachments
For Gerrit Dashboard: QTBUG-14766 | ||||||
---|---|---|---|---|---|---|
# | Subject | Branch | Project | Status | CR | V |
48866,2 | Fixed potential access violation in QPixmap::copy() for <32 bit pixmaps. | release | qt/qtbase | Status: MERGED | +2 | 0 |
53999,1 | Fixed potential access violation in QPixmap::copy() for <32 bit pixmaps. | 4.8 | qt/qt | Status: MERGED | +2 | 0 |