Fix loading of image files with wrong, but known, file name extension
If QImageReader recognized the suffix of a file, it would by default not check if the file contents matched the claimed format. Hence, a valid but misnamed image file would fail to load. Fix by adding contents check for suffix-recognized files. [ChangeLog][QtGui][Image] Loading of image files having a file name suffix for a different image file type has been fixed. QImageReader will now ask the suffix format handler to confirm the file contents (canRead()), and fall back to normal file content recognition on failure. This implies a slight behavior change in QImageReader::loopCount(), ::imageCount() and ::nextImageDelay(): For an unreadable file with a recognized suffix, they would earlier return 0, while they now will return -1, i.e. error as per the documentation. Fixes: QTBUG-42540 Fixes: QTBUG-68787 Change-Id: I205e83f29ed7190cbcae95dab960232544d012f6 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>bb10
parent
7f948d9eff
commit
82aabafada
|
|
@ -197,7 +197,7 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device,
|
|||
|
||||
#ifdef QIMAGEREADER_DEBUG
|
||||
qDebug() << "QImageReader::createReadHandler( device =" << (void *)device << ", format =" << format << "),"
|
||||
<< keyMap.size() << "plugins available: " << keyMap.values();
|
||||
<< keyMap.uniqueKeys().size() << "plugins available: " << keyMap;
|
||||
#endif
|
||||
|
||||
int suffixPluginIndex = -1;
|
||||
|
|
@ -325,6 +325,29 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device,
|
|||
#endif
|
||||
}
|
||||
|
||||
if (handler && device && !suffix.isEmpty()) {
|
||||
Q_ASSERT(qobject_cast<QFile *>(device));
|
||||
// We have a file claiming to be of a recognized format. Now confirm that
|
||||
// the handler also recognizes the file contents.
|
||||
const qint64 pos = device->pos();
|
||||
handler->setDevice(device);
|
||||
if (!form.isEmpty())
|
||||
handler->setFormat(form);
|
||||
bool canRead = handler->canRead();
|
||||
device->seek(pos);
|
||||
if (canRead) {
|
||||
// ok, we're done.
|
||||
return handler;
|
||||
}
|
||||
#ifdef QIMAGEREADER_DEBUG
|
||||
qDebug() << "QImageReader::createReadHandler: the" << suffix << "handler can not read this file";
|
||||
#endif
|
||||
// File may still be valid, just with wrong suffix, so fall back to
|
||||
// finding a handler based on contents, below.
|
||||
delete handler;
|
||||
handler = nullptr;
|
||||
}
|
||||
|
||||
#ifndef QT_NO_IMAGEFORMATPLUGIN
|
||||
if (!handler && (autoDetectImageFormat || ignoresFormatAndExtension)) {
|
||||
// check if any of our plugins recognize the file from its contents.
|
||||
|
|
@ -336,7 +359,7 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device,
|
|||
if (plugin && plugin->capabilities(device, QByteArray()) & QImageIOPlugin::CanRead) {
|
||||
handler = plugin->create(device, testFormat);
|
||||
#ifdef QIMAGEREADER_DEBUG
|
||||
qDebug() << "QImageReader::createReadHandler: the" << keyMap.keys().at(i) << "plugin can read this data";
|
||||
qDebug() << "QImageReader::createReadHandler: the" << keyMap.value(i) << "plugin can read this data";
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -164,7 +164,7 @@ void tst_QIcoImageFormat::imageCount_data()
|
|||
QTest::newRow("16px,32px - 16 colors") << "valid/TIMER01.ICO" << 2;
|
||||
QTest::newRow("16px16c, 32px32c, 32px256c 1") << "valid/WORLD.ico" << 3;
|
||||
QTest::newRow("16px16c, 32px32c, 32px256c 2") << "valid/WORLDH.ico" << 3;
|
||||
QTest::newRow("invalid floppy (first 8 bytes = 0xff)") << "invalid/35floppy.ico" << 0;
|
||||
QTest::newRow("invalid floppy (first 8 bytes = 0xff)") << "invalid/35floppy.ico" << -1;
|
||||
QTest::newRow("includes 32BPP w/alpha") << "valid/semitransparent.ico" << 9;
|
||||
QTest::newRow("PNG compression") << "valid/Qt.ico" << 4;
|
||||
QTest::newRow("CUR file") << "valid/yellow.cur" << 1;
|
||||
|
|
@ -177,7 +177,6 @@ void tst_QIcoImageFormat::imageCount()
|
|||
|
||||
QImageReader reader(m_IconPath + QLatin1Char('/') + fileName);
|
||||
QCOMPARE(reader.imageCount(), count);
|
||||
|
||||
}
|
||||
|
||||
void tst_QIcoImageFormat::jumpToNextImage_data()
|
||||
|
|
@ -218,7 +217,7 @@ void tst_QIcoImageFormat::loopCount_data()
|
|||
QTest::addColumn<int>("count");
|
||||
|
||||
QTest::newRow("floppy (16px,32px - 16 colors)") << "valid/35FLOPPY.ICO" << 0;
|
||||
QTest::newRow("invalid floppy (first 8 bytes = 0xff)") << "invalid/35floppy.ico" << 0;
|
||||
QTest::newRow("invalid floppy (first 8 bytes = 0xff)") << "invalid/35floppy.ico" << -1;
|
||||
}
|
||||
|
||||
void tst_QIcoImageFormat::loopCount()
|
||||
|
|
@ -228,6 +227,7 @@ void tst_QIcoImageFormat::loopCount()
|
|||
|
||||
QImageReader reader(m_IconPath + QLatin1Char('/') + fileName);
|
||||
QCOMPARE(reader.loopCount(), count);
|
||||
QCOMPARE(reader.canRead(), count < 0 ? false : true);
|
||||
}
|
||||
|
||||
void tst_QIcoImageFormat::nextImageDelay_data()
|
||||
|
|
@ -256,7 +256,7 @@ void tst_QIcoImageFormat::nextImageDelay()
|
|||
|
||||
QImageReader reader(m_IconPath + QLatin1Char('/') + fileName);
|
||||
if (count == -1) {
|
||||
QCOMPARE(reader.nextImageDelay(), 0);
|
||||
QCOMPARE(reader.nextImageDelay(), -1);
|
||||
} else {
|
||||
int i;
|
||||
for (i = 0; i < count; i++) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue