From 4469fbecd4e004979dada2da72573c06719fee3c Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 26 Aug 2016 11:40:54 +0200 Subject: QSvgIconEngine::addFile(): Use QMimeDatabase to determine file type Introduce an enumeration to describe the file type and use QMimeDatbase to determine the type. This will detect SVG files also in the case resource aliases without suffixes are used. As a drive by, do not pass compressed SVG files to QPixmap when QT_NO_COMPRESS is defined, as this likely results in garbage. Task-number: QTBUG-55388 Change-Id: Ib8bafca60e9238412a5c7edf560d487e512b8fd0 Reviewed-by: Eirik Aavitsland --- .../iconengines/svgiconengine/qsvgiconengine.cpp | 56 +++++++++++++++------- 1 file changed, 38 insertions(+), 18 deletions(-) (limited to 'src/plugins/iconengines/svgiconengine/qsvgiconengine.cpp') diff --git a/src/plugins/iconengines/svgiconengine/qsvgiconengine.cpp b/src/plugins/iconengines/svgiconengine/qsvgiconengine.cpp index 713f2ad..1342c0b 100644 --- a/src/plugins/iconengines/svgiconengine/qsvgiconengine.cpp +++ b/src/plugins/iconengines/svgiconengine/qsvgiconengine.cpp @@ -45,6 +45,8 @@ #include "qsvgrenderer.h" #include "qpixmapcache.h" #include "qfileinfo.h" +#include +#include #include #include "qdebug.h" #include @@ -201,31 +203,49 @@ void QSvgIconEngine::addPixmap(const QPixmap &pixmap, QIcon::Mode mode, d->addedPixmaps->insert(d->hashKey(mode, state), pixmap); } +enum FileType { OtherFile, SvgFile, CompressedSvgFile }; + +static FileType fileType(const QFileInfo &fi) +{ + const QString &abs = fi.absoluteFilePath(); + if (abs.endsWith(QLatin1String(".svg"), Qt::CaseInsensitive)) + return SvgFile; + if (abs.endsWith(QLatin1String(".svgz"), Qt::CaseInsensitive) + || abs.endsWith(QLatin1String(".svg.gz"), Qt::CaseInsensitive)) { + return CompressedSvgFile; + } +#ifndef QT_NO_MIMETYPE + const QString &mimeTypeName = QMimeDatabase().mimeTypeForFile(fi).name(); + if (mimeTypeName == QLatin1String("image/svg+xml")) + return SvgFile; + if (mimeTypeName == QLatin1String("image/svg+xml-compressed")) + return CompressedSvgFile; +#endif // !QT_NO_MIMETYPE + return OtherFile; +} void QSvgIconEngine::addFile(const QString &fileName, const QSize &, QIcon::Mode mode, QIcon::State state) { if (!fileName.isEmpty()) { - QString abs = fileName; - if (fileName.at(0) != QLatin1Char(':')) - abs = QFileInfo(fileName).absoluteFilePath(); - if (abs.endsWith(QLatin1String(".svg"), Qt::CaseInsensitive) + const QFileInfo fi(fileName); + const QString abs = fi.absoluteFilePath(); + const FileType type = fileType(fi); #ifndef QT_NO_COMPRESS - || abs.endsWith(QLatin1String(".svgz"), Qt::CaseInsensitive) - || abs.endsWith(QLatin1String(".svg.gz"), Qt::CaseInsensitive) + if (type == SvgFile || type == CompressedSvgFile) { +#else + if (type == SvgFile) { #endif - ) - { - QSvgRenderer renderer(abs); - if (renderer.isValid()) { - d->stepSerialNum(); - d->svgFiles.insert(d->hashKey(mode, state), abs); - } - } else { - QPixmap pm(abs); - if (!pm.isNull()) - addPixmap(pm, mode, state); - } + QSvgRenderer renderer(abs); + if (renderer.isValid()) { + d->stepSerialNum(); + d->svgFiles.insert(d->hashKey(mode, state), abs); + } + } else if (type == OtherFile) { + QPixmap pm(abs); + if (!pm.isNull()) + addPixmap(pm, mode, state); + } } } -- cgit v1.2.1 From 78bc427395116bfaf3d99134f42aec5310020f8e Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 6 Sep 2016 17:44:08 +0200 Subject: Fix UB (signed overflow) in QSvgIconEnginePrivate::pmcKey() Found by UBsan: qsvgiconengine.cpp:64:84: runtime error: left shift of 537133056 by 4 places cannot be represented in type 'int' Fix by casting to qint64 at the start of the shift-or chain. The total cumulative shift is by 28 places, so 64 bits should be enough to not overflow anymore. Change-Id: Ia37bc98c5af67a4de10fb9807addd369110f36d2 Reviewed-by: Edward Welbourne Reviewed-by: Thiago Macieira --- src/plugins/iconengines/svgiconengine/qsvgiconengine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/plugins/iconengines/svgiconengine/qsvgiconengine.cpp') diff --git a/src/plugins/iconengines/svgiconengine/qsvgiconengine.cpp b/src/plugins/iconengines/svgiconengine/qsvgiconengine.cpp index 086f5a9..0a01abe 100644 --- a/src/plugins/iconengines/svgiconengine/qsvgiconengine.cpp +++ b/src/plugins/iconengines/svgiconengine/qsvgiconengine.cpp @@ -61,7 +61,7 @@ public: QString pmcKey(const QSize &size, QIcon::Mode mode, QIcon::State state) { return QLatin1String("$qt_svgicon_") + QString::number(serialNum, 16).append(QLatin1Char('_')) - + QString::number((((((size.width()<<11)|size.height())<<11)|mode)<<4)|state, 16); } + + QString::number((((((qint64(size.width()) << 11) | size.height()) << 11) | mode) << 4) | state, 16); } void stepSerialNum() { serialNum = lastSerialNum.fetchAndAddRelaxed(1); } -- cgit v1.2.1