summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gui/image/qpaintengine_pic.cpp17
-rw-r--r--src/gui/image/qpicture.cpp6
-rw-r--r--src/gui/image/qpicture_p.h1
-rw-r--r--src/gui/painting/qcolorspace.cpp4
-rw-r--r--src/gui/painting/qpainter.cpp4
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)