diff options
| -rw-r--r-- | src/gui/image/qpaintengine_pic.cpp | 17 | ||||
| -rw-r--r-- | src/gui/image/qpicture.cpp | 6 | ||||
| -rw-r--r-- | src/gui/image/qpicture_p.h | 1 | ||||
| -rw-r--r-- | src/gui/painting/qcolorspace.cpp | 4 | ||||
| -rw-r--r-- | src/gui/painting/qpainter.cpp | 4 |
5 files changed, 25 insertions, 7 deletions
diff --git a/src/gui/image/qpaintengine_pic.cpp b/src/gui/image/qpaintengine_pic.cpp index ba4888cef75..b151c3b2d18 100644 --- a/src/gui/image/qpaintengine_pic.cpp +++ b/src/gui/image/qpaintengine_pic.cpp @@ -31,6 +31,7 @@ public: QDataStream s; QPainter *pt; QPicturePrivate *pic_d; + bool sizeLimitExceeded = false; }; QPicturePaintEngine::QPicturePaintEngine() @@ -68,6 +69,7 @@ bool QPicturePaintEngine::begin(QPaintDevice *pd) d->s.setVersion(d->pic_d->formatMajor); d->pic_d->pictb.open(QIODevice::WriteOnly | QIODevice::Truncate); + d->sizeLimitExceeded = false; d->s.writeRawData(qt_mfhdr_tag, 4); d->s << (quint16) 0 << (quint16) d->pic_d->formatMajor << (quint16) d->pic_d->formatMinor; d->s << (quint8) QPicturePrivate::PdcBegin << (quint8) sizeof(qint32); @@ -109,7 +111,7 @@ bool QPicturePaintEngine::end() d->s << cs; // write checksum d->pic_d->pictb.close(); setActive(false); - return true; + return !d->sizeLimitExceeded; } #define SERIALIZE_CMD(c) \ @@ -286,6 +288,19 @@ void QPicturePaintEngine::updateRenderHints(QPainter::RenderHints hints) void QPicturePaintEngine::writeCmdLength(int pos, const QRectF &r, bool corr) { Q_D(QPicturePaintEngine); + + constexpr int sizeLimit = std::numeric_limits<int>::max() - 8; // Leave room for ending bytes + if (d->sizeLimitExceeded || d->pic_d->pictb.pos() > sizeLimit) { + d->pic_d->trecs--; // Remove last command added, started by SERIALIZE_CMD + d->pic_d->pictb.seek(pos - 2); + d->pic_d->pictbData.resize(pos - 2); + if (!d->sizeLimitExceeded) { + d->sizeLimitExceeded = true; + qWarning("QPicture: size limit exceeded, will be truncated"); + } + return; + } + int newpos = d->pic_d->pictb.pos(); // new position int length = newpos - pos; QRectF br(r); diff --git a/src/gui/image/qpicture.cpp b/src/gui/image/qpicture.cpp index ac0525d7abf..db2a5fd9ba9 100644 --- a/src/gui/image/qpicture.cpp +++ b/src/gui/image/qpicture.cpp @@ -970,7 +970,8 @@ QPicture& QPicture::operator=(const QPicture &p) Constructs a QPicturePrivate */ QPicturePrivate::QPicturePrivate() - : in_memory_only(false) + : pictb(&pictbData), + in_memory_only(false) { } @@ -980,7 +981,8 @@ QPicturePrivate::QPicturePrivate() Copy-Constructs a QPicturePrivate. Needed when detaching. */ QPicturePrivate::QPicturePrivate(const QPicturePrivate &other) - : trecs(other.trecs), + : pictb(&pictbData), + trecs(other.trecs), formatOk(other.formatOk), formatMinor(other.formatMinor), brect(other.brect), diff --git a/src/gui/image/qpicture_p.h b/src/gui/image/qpicture_p.h index c512f49320b..1d8142f44b7 100644 --- a/src/gui/image/qpicture_p.h +++ b/src/gui/image/qpicture_p.h @@ -113,6 +113,7 @@ public: bool checkFormat(); void resetFormat(); + QByteArray pictbData; QBuffer pictb; int trecs; bool formatOk; diff --git a/src/gui/painting/qcolorspace.cpp b/src/gui/painting/qcolorspace.cpp index c43d133dd1e..9149971b999 100644 --- a/src/gui/painting/qcolorspace.cpp +++ b/src/gui/painting/qcolorspace.cpp @@ -1206,12 +1206,12 @@ QByteArray QColorSpace::iccProfile() const QColorSpace QColorSpace::fromIccProfile(const QByteArray &iccProfile) { // Must detach if input is fromRawData(); nullTerminated() is trick to do that and nothing else - const QByteArray ownedIccProfile(iccProfile.nullTerminated()); + QByteArray ownedIccProfile = iccProfile.nullTerminated(); QColorSpace colorSpace; if (QIcc::fromIccProfile(ownedIccProfile, &colorSpace)) return colorSpace; colorSpace.detach(); - colorSpace.d_ptr->iccProfile = ownedIccProfile; + colorSpace.d_ptr->iccProfile = std::move(ownedIccProfile); return colorSpace; } diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 4c5414f177e..2b6a8a858f9 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -6498,8 +6498,8 @@ void QPainter::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPo qt_painter_thread_test(d->device->devType(), d->engine->type(), "drawTiledPixmap()"); #endif - qreal sw = pixmap.width(); - qreal sh = pixmap.height(); + const qreal sw = pixmap.width() / pixmap.devicePixelRatio(); + const qreal sh = pixmap.height() / pixmap.devicePixelRatio(); qreal sx = sp.x(); qreal sy = sp.y(); if (sx < 0) |
