kumquat-buildroot/package/qt5/qt5base/0010-Avoid-processing-intensive-painting-of-high-number-o.patch
Quentin Schulz 9151eab3c7 package/qt5/qt5base: fix CVE-2021-38593
5.15.2 is the last public release of 5.15 and does not contain this CVE
fix. However, >=6.1.2 and >5.12.12 all contain the necessary patches so
let's port them to 5.15.2.

Technically only the first two patches are required to patch the CVE.
However, the second patch introduces a regression that is fixed in the third
patch.

The patches are taken from KDE kde/5.15 git branch.

Cc: Quentin Schulz <foss+buildroot@0leil.net>
Signed-off-by: Quentin Schulz <quentin.schulz@theobroma-systems.com>
Signed-off-by: Yann E. MORIN <yann.morin.1998@free.fr>
2022-01-21 21:50:27 +01:00

164 lines
5.9 KiB
Diff

From 307bc02e379e63aa9b7a3d21bbcd9c84d34c600f Mon Sep 17 00:00:00 2001
From: Eirik Aavitsland <eirik.aavitsland@qt.io>
Date: Tue, 13 Apr 2021 14:23:45 +0200
Subject: [PATCH] Avoid processing-intensive painting of high number of tiny
dashes
When stroking a dashed path, an unnecessary amount of processing would
be spent if there is a huge number of dashes visible, e.g. because of
scaling. Since the dashes are too small to be indivdually visible
anyway, just replace with a semi-transparent solid line for such
cases.
Pick-to: 6.1 6.0 5.15
Change-Id: I9e9f7861257ad5bce46a0cf113d1a9d7824911e6
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit f4d791b330d02777fcaf02938732892eb3167e9b)
* asturmlechner 2021-08-21:
Conflict from preceding 94dd2ceb in dev branch:
src/gui/painting/qpaintengineex.cpp
Resolved via:
if (pen.style() > Qt::SolidLine) {
QRectF cpRect = path.controlPointRect();
const QTransform &xf = state()->matrix;
- if (pen.isCosmetic()) {
+ if (qt_pen_is_cosmetic(pen, state()->renderHints)){
clipRect = d->exDeviceRect;
cpRect.translate(xf.dx(), xf.dy());
} else {
FTBFS from preceding 471e4fcb in dev branch changing QVector to QList:
Resolved via:
QRectF extentRect = cpRect.adjusted(-pw, -pw, pw, pw) & clipRect;
qreal extent = qMax(extentRect.width(), extentRect.height());
qreal patternLength = 0;
- const QList<qreal> pattern = pen.dashPattern();
+ const QVector<qreal> pattern = pen.dashPattern();
const int patternSize = qMin(pattern.size(), 32);
for (int i = 0; i < patternSize; i++)
patternLength += qMax(pattern.at(i), qreal(0));
[Retrieved from: https://invent.kde.org/qt/qt/qtbase/-/commit/081d835c040a90f8ee76807354355062ac521dfb]
Signed-off-by: Quentin Schulz <quentin.schulz@theobroma-systems.com>
---
src/gui/painting/qpaintengineex.cpp | 44 +++++++++++++++----
.../other/lancelot/scripts/tinydashes.qps | 34 ++++++++++++++
2 files changed, 69 insertions(+), 9 deletions(-)
create mode 100644 tests/auto/other/lancelot/scripts/tinydashes.qps
diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp
index 5d8f89eadd..55fdb0c2a0 100644
--- a/src/gui/painting/qpaintengineex.cpp
+++ b/src/gui/painting/qpaintengineex.cpp
@@ -385,7 +385,7 @@ QPainterState *QPaintEngineEx::createState(QPainterState *orig) const
Q_GUI_EXPORT extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale); // qtransform.cpp
-void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen)
+void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &inPen)
{
#ifdef QT_DEBUG_DRAW
qDebug() << "QPaintEngineEx::stroke()" << pen;
@@ -403,6 +403,38 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen)
d->stroker.setCubicToHook(qpaintengineex_cubicTo);
}
+ QRectF clipRect;
+ QPen pen = inPen;
+ if (pen.style() > Qt::SolidLine) {
+ QRectF cpRect = path.controlPointRect();
+ const QTransform &xf = state()->matrix;
+ if (qt_pen_is_cosmetic(pen, state()->renderHints)){
+ clipRect = d->exDeviceRect;
+ cpRect.translate(xf.dx(), xf.dy());
+ } else {
+ clipRect = xf.inverted().mapRect(QRectF(d->exDeviceRect));
+ }
+ // Check to avoid generating unwieldy amount of dashes that will not be visible anyway
+ QRectF extentRect = cpRect & clipRect;
+ qreal extent = qMax(extentRect.width(), extentRect.height());
+ qreal patternLength = 0;
+ const QVector<qreal> pattern = pen.dashPattern();
+ const int patternSize = qMin(pattern.size(), 32);
+ for (int i = 0; i < patternSize; i++)
+ patternLength += qMax(pattern.at(i), qreal(0));
+ if (pen.widthF())
+ patternLength *= pen.widthF();
+ if (qFuzzyIsNull(patternLength)) {
+ pen.setStyle(Qt::NoPen);
+ } else if (extent / patternLength > 10000) {
+ // approximate stream of tiny dashes with semi-transparent solid line
+ pen.setStyle(Qt::SolidLine);
+ QColor color(pen.color());
+ color.setAlpha(color.alpha() / 2);
+ pen.setColor(color);
+ }
+ }
+
if (!qpen_fast_equals(pen, d->strokerPen)) {
d->strokerPen = pen;
d->stroker.setJoinStyle(pen.joinStyle());
@@ -430,14 +462,8 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen)
return;
}
- if (pen.style() > Qt::SolidLine) {
- if (qt_pen_is_cosmetic(pen, state()->renderHints)){
- d->activeStroker->setClipRect(d->exDeviceRect);
- } else {
- QRectF clipRect = state()->matrix.inverted().mapRect(QRectF(d->exDeviceRect));
- d->activeStroker->setClipRect(clipRect);
- }
- }
+ if (!clipRect.isNull())
+ d->activeStroker->setClipRect(clipRect);
if (d->activeStroker == &d->stroker)
d->stroker.setForceOpen(path.hasExplicitOpen());
diff --git a/tests/auto/other/lancelot/scripts/tinydashes.qps b/tests/auto/other/lancelot/scripts/tinydashes.qps
new file mode 100644
index 0000000000..d41ced7f5f
--- /dev/null
+++ b/tests/auto/other/lancelot/scripts/tinydashes.qps
@@ -0,0 +1,34 @@
+# Version: 1
+# CheckVsReference: 5%
+
+path_addEllipse mypath 20.0 20.0 200.0 200.0
+
+save
+setPen blue 20 SolidLine FlatCap
+pen_setCosmetic true
+pen_setDashPattern [ 0.0004 0.0004 ]
+setBrush yellow
+
+drawPath mypath
+translate 300 0
+setRenderHint Antialiasing true
+drawPath mypath
+restore
+
+path_addEllipse bigpath 200000.0 200000.0 2000000.0 2000000.0
+
+setPen blue 20 DotLine FlatCap
+setBrush yellow
+
+save
+translate 0 300
+scale 0.0001 0.00011
+drawPath bigpath
+restore
+
+save
+translate 300 300
+setRenderHint Antialiasing true
+scale 0.0001 0.00011
+drawPath bigpath
+restore
--
2.34.1