QPixmap: More safe failing if qApp is not a QGuiApplication

It can happen that QDataStream is fed a QVariant that contains a QPixmap
representation, that will make the application crash when trying to
restore it

This is specially important for cases in which applications expose dbus
interfaces with QVariantMaps

Change-Id: Ife4feaef30f30e7e27d88464bd6b2a247f743123
Reported-by: Fabian Vogt <fabian@ritter-vogt.de>
Reviewed-by: Fabian Vogt <fabian@ritter-vogt.de>
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Albert Astals Cid 2019-03-15 11:01:31 +01:00
parent b01248ebbd
commit 85a9009f25
4 changed files with 88 additions and 0 deletions

View File

@ -1543,6 +1543,11 @@ QPixmap QPixmap::fromImage(const QImage &image, Qt::ImageConversionFlags flags)
if (image.isNull())
return QPixmap();
if (Q_UNLIKELY(!qobject_cast<QGuiApplication *>(QCoreApplication::instance()))) {
qWarning("QPixmap::fromImage: QPixmap cannot be created without a QGuiApplication");
return QPixmap();
}
QScopedPointer<QPlatformPixmap> data(QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(QPlatformPixmap::PixmapType));
data->fromImage(image, flags);
return QPixmap(data.take());
@ -1565,6 +1570,11 @@ QPixmap QPixmap::fromImageInPlace(QImage &image, Qt::ImageConversionFlags flags)
if (image.isNull())
return QPixmap();
if (Q_UNLIKELY(!qobject_cast<QGuiApplication *>(QCoreApplication::instance()))) {
qWarning("QPixmap::fromImageInPlace: QPixmap cannot be created without a QGuiApplication");
return QPixmap();
}
QScopedPointer<QPlatformPixmap> data(QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(QPlatformPixmap::PixmapType));
data->fromImageInPlace(image, flags);
return QPixmap(data.take());
@ -1584,6 +1594,11 @@ QPixmap QPixmap::fromImageInPlace(QImage &image, Qt::ImageConversionFlags flags)
*/
QPixmap QPixmap::fromImageReader(QImageReader *imageReader, Qt::ImageConversionFlags flags)
{
if (Q_UNLIKELY(!qobject_cast<QGuiApplication *>(QCoreApplication::instance()))) {
qWarning("QPixmap::fromImageReader: QPixmap cannot be created without a QGuiApplication");
return QPixmap();
}
QScopedPointer<QPlatformPixmap> data(QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(QPlatformPixmap::PixmapType));
data->fromImageReader(imageReader, flags);
return QPixmap(data.take());

View File

@ -0,0 +1,4 @@
CONFIG += testcase
TARGET = tst_qdatastream_core_pixmap
QT += testlib
SOURCES = tst_qdatastream_core_pixmap.cpp

View File

@ -0,0 +1,68 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtTest/QtTest>
#include <QtGui/QBitmap>
#include <QtGui/QPalette>
#include <QtGui/QPixmap>
#include <QtGui/QPicture>
#include <QtGui/QTextLength>
#include <QtGui/QPainter>
#include <QtGui/QPen>
class tst_QDataStream : public QObject
{
Q_OBJECT
private slots:
void stream_with_pixmap();
};
void tst_QDataStream::stream_with_pixmap()
{
// This is a QVariantMap with a 3x3 red QPixmap and two strings inside
const QByteArray ba = QByteArray::fromBase64("AAAAAwAAAAIAegAAAAoAAAAACgB0AGgAZQByAGUAAAACAHAAAABBAAAAAAGJUE5HDQoaCgAAAA1JSERSAAAAAwAAAAMIAgAAANlKIugAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAAQSURBVAiZY/zPAAVMDJgsAB1bAQXZn5ieAAAAAElFTkSuQmCCAAAAAgBhAAAACgAAAAAKAGgAZQBsAGwAbw==");
QImage dummy; // Needed to make sure qtGui is loaded
QTest::ignoreMessage(QtWarningMsg, "QPixmap::fromImageInPlace: QPixmap cannot be created without a QGuiApplication");
QVariantMap map;
QDataStream d(ba);
d.setVersion(QDataStream::Qt_5_12);
d >> map;
QCOMPARE(map["a"].toString(), QString("hello"));
QCOMPARE(map["p"].value<QPixmap>(), QPixmap()); // the pixmap is null because this is not a QGuiApplication
QCOMPARE(map["z"].toString(), QString("there"));
}
QTEST_GUILESS_MAIN(tst_QDataStream)
#include "tst_qdatastream_core_pixmap.moc"

View File

@ -6,6 +6,7 @@ SUBDIRS = \
qcborvalue \
qcborvalue_json \
qdatastream \
qdatastream_core_pixmap \
qtextstream \
qxmlstream