summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com>2009-09-17 10:21:49 +0200
committerEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com>2009-09-17 10:25:37 +0200
commit603c423fc2ee2b9393e3c288e76354de0e0c1cc7 (patch)
tree1c8168c14f9443a7e9c8dced5f0e0737d9b4482e
parent9cef27f506e15681f9935a1c00c9df3c6271d5f2 (diff)
Fix crash or painting error when drawing dashed lines with penWidth > 1
Since the width is multiplied into the dash, it needs to be divided out, otherwise you can get a dashOffset which is greater than the pattern at the index, and the dash can become negative. This will in turn lead to passing a negative width to the rasterizer, which at some point will get cast to an unsigned int and overflow. Depending on the position of the line and size of the buffer, this will either crash or produce garbled output. Task-number: QT-4444 Reviewed-by: Samuel
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp2
-rw-r--r--src/gui/painting/qrasterizer.cpp4
-rw-r--r--tests/auto/qpainter/tst_qpainter.cpp25
3 files changed, 29 insertions, 2 deletions
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index bd12fdbf01..bcea1ec512 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -3564,7 +3564,7 @@ void QRasterPaintEnginePrivate::rasterizeLine_dashed(QLineF line,
if (dash >= length) {
dash = length;
- *dashOffset += dash;
+ *dashOffset += dash / width;
length = 0;
} else {
*dashOffset = 0;
diff --git a/src/gui/painting/qrasterizer.cpp b/src/gui/painting/qrasterizer.cpp
index 4500756f31..2b6791ddca 100644
--- a/src/gui/painting/qrasterizer.cpp
+++ b/src/gui/painting/qrasterizer.cpp
@@ -706,10 +706,12 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width,
if (a == b || width == 0 || d->clipRect.isEmpty())
return;
+ Q_ASSERT(width > 0.0);
+
QPointF pa = a;
QPointF pb = b;
- QPointF offs = QPointF(qAbs(b.y() - a.y()), qAbs(b.x() - a.x())) * width * 0.5;
+ QPointF offs = QPointF(qAbs(b.y() - a.y()), qAbs(b.x() - a.x())) * width * 0.5;
if (squareCap)
offs += QPointF(offs.y(), offs.x());
const QRectF clip(d->clipRect.topLeft() - offs, d->clipRect.bottomRight() + QPoint(1, 1) + offs);
diff --git a/tests/auto/qpainter/tst_qpainter.cpp b/tests/auto/qpainter/tst_qpainter.cpp
index e434ed6b53..c0eac21e41 100644
--- a/tests/auto/qpainter/tst_qpainter.cpp
+++ b/tests/auto/qpainter/tst_qpainter.cpp
@@ -230,6 +230,8 @@ private slots:
void zeroOpacity();
void emptyClip();
+ void taskQT4444_dontOverflowDashOffset();
+
private:
void fillData();
QColor baseColor( int k, int intensity=255 );
@@ -4239,5 +4241,28 @@ void tst_QPainter::emptyClip()
p.fillPath(path, Qt::green);
}
+void tst_QPainter::taskQT4444_dontOverflowDashOffset()
+{
+ QPainter p;
+
+ QPen pen;
+ pen.setWidth(2);
+ pen.setStyle(Qt::DashDotLine);
+
+ QPointF point[4];
+ point[0] = QPointF(182.50868749707968,347.78457234212630);
+ point[1] = QPointF(182.50868749707968,107.22501998401277);
+ point[2] = QPointF(182.50868749707968,107.22501998401277);
+ point[3] = QPointF(520.46600762283651,107.22501998401277);
+
+ QImage crashImage(QSize(1000, 120), QImage::Format_ARGB32_Premultiplied);
+ p.begin(&crashImage);
+ p.setPen(pen);
+ p.drawLines(point, 2);
+ p.end();
+
+ QVERIFY(true); // Don't crash
+}
+
QTEST_MAIN(tst_QPainter)
#include "tst_qpainter.moc"