From 8513bcd90cc3900f9c32e59e0823f621ea6eea1d Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Mon, 11 Oct 2021 13:03:44 +0200 Subject: Fix caching of parsed border color values in CSS parser When parsing CSS, a border-color value is parsed as four brushes, as css allows assigning up to four values, one for each side. When applying the CSS to the HTML, we accessed it as a color value, which overwrote the parsed value with a QColor. So while we had a valid parsed value (and didn't re-parse), the code accessing that value still expected it to be a list, and thus failed to retrieve the data. There are several ways to fix that, but the cleanest way without introducing any performance penalty from repeatedly parsing (and in fact removing a parse of the string into a color) is to enable colorValue to interpret an already parsed value that is a list without overwriting the parsed value again. To avoid similar issues in the future, add assert that the parsed value has the right type in brushValues. As a drive-by, speed things up further by making use of qMetaTypeId being constexpr, which allows for it to be used in a switch statement. Add a test case. Fixes: QTBUG-96603 Pick-to: 6.2 5.15 Change-Id: Icdbff874daedc91bff497cd0cd1d99e4c713217c Reviewed-by: Qt CI Bot Reviewed-by: Lars Knoll --- src/gui/text/qcssparser.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'src/gui/text') diff --git a/src/gui/text/qcssparser.cpp b/src/gui/text/qcssparser.cpp index 574436d6f6..da3de4d651 100644 --- a/src/gui/text/qcssparser.cpp +++ b/src/gui/text/qcssparser.cpp @@ -1460,10 +1460,18 @@ QColor Declaration::colorValue(const QPalette &pal) const return QColor(); if (d->parsed.isValid()) { - if (d->parsed.userType() == QMetaType::QColor) + switch (d->parsed.typeId()) { + case qMetaTypeId(): return qvariant_cast(d->parsed); - if (d->parsed.userType() == QMetaType::Int) + case qMetaTypeId(): return pal.color((QPalette::ColorRole)(d->parsed.toInt())); + case qMetaTypeId>(): + if (d->parsed.toList().size() == 1) { + const auto &value = d->parsed.toList().at(0); + return qvariant_cast(value); + } + break; + } } ColorData color = parseColorValue(d->values.at(0)); @@ -1507,6 +1515,7 @@ void Declaration::brushValues(QBrush *c, const QPalette &pal) const int i = 0; if (d->parsed.isValid()) { needParse = 0; + Q_ASSERT(d->parsed.metaType() == QMetaType::fromType>()); QList v = d->parsed.toList(); for (i = 0; i < qMin(v.count(), 4); i++) { if (v.at(i).userType() == QMetaType::QBrush) { -- cgit v1.2.3