From cfc616978b52a396b2ef6900546f7fc086d7cab3 Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Thu, 8 Apr 2021 13:19:52 +0200 Subject: [PATCH 3/9] Make image handler accept UTF-16/UTF-32 encoded SVGs The canRead() header checks assumed 8 bit encoding. Pick-to: 6.1 6.0 5.15 Fixes: QTBUG-90744 Change-Id: Ibe934fe9ed31b89ee0fbfc4562aa66ab1b359225 Reviewed-by: Allan Sandfeld Jensen (cherry picked from commit 45fb1f07eaa984af40fca9f12b8f3d27f7b0e9ac) --- .../imageformats/svg/qsvgiohandler.cpp | 37 +++++++++++------- tests/auto/qsvgplugin/simple_Utf16BE.svg | Bin 0 -> 228 bytes tests/auto/qsvgplugin/simple_Utf16LE.svg | Bin 0 -> 228 bytes tests/auto/qsvgplugin/simple_Utf32BE.svg | Bin 0 -> 456 bytes tests/auto/qsvgplugin/simple_Utf32LE.svg | Bin 0 -> 456 bytes tests/auto/qsvgplugin/simple_Utf8.svg | 3 ++ tests/auto/qsvgplugin/tst_qsvgplugin.cpp | 32 +++++++++++++++ 7 files changed, 57 insertions(+), 15 deletions(-) create mode 100644 tests/auto/qsvgplugin/simple_Utf16BE.svg create mode 100644 tests/auto/qsvgplugin/simple_Utf16LE.svg create mode 100644 tests/auto/qsvgplugin/simple_Utf32BE.svg create mode 100644 tests/auto/qsvgplugin/simple_Utf32LE.svg create mode 100644 tests/auto/qsvgplugin/simple_Utf8.svg diff --git a/src/plugins/imageformats/svg/qsvgiohandler.cpp b/src/plugins/imageformats/svg/qsvgiohandler.cpp index bd39b2a..4136aaf 100644 --- a/src/plugins/imageformats/svg/qsvgiohandler.cpp +++ b/src/plugins/imageformats/svg/qsvgiohandler.cpp @@ -118,6 +118,24 @@ QSvgIOHandler::~QSvgIOHandler() delete d; } +static bool isPossiblySvg(QIODevice *device, bool *isCompressed = nullptr) +{ + constexpr int bufSize = 64; + char buf[bufSize]; + const qint64 readLen = device->peek(buf, bufSize); + if (readLen < 8) + return false; +# ifndef QT_NO_COMPRESS + if (quint8(buf[0]) == 0x1f && quint8(buf[1]) == 0x8b) { + if (isCompressed) + *isCompressed = true; + return true; + } +# endif + QTextStream str(QByteArray::fromRawData(buf, readLen)); + QByteArray ba = str.read(16).trimmed().toLatin1(); + return ba.startsWith("loaded && !d->readDone) return true; // Will happen if we have been asked for the size - QByteArray buf = device()->peek(16); -#ifndef QT_NO_COMPRESS - if (buf.startsWith("\x1f\x8b")) { - setFormat("svgz"); - return true; - } else -#endif - if (buf.contains("peek(16); - return -#ifndef QT_NO_COMPRESS - buf.startsWith("\x1f\x8b") || -#endif - buf.contains("("filename"); + + QTest::newRow("utf-8") << QFINDTESTDATA("simple_Utf8.svg"); + QTest::newRow("utf-16LE") << QFINDTESTDATA("simple_Utf16LE.svg"); + QTest::newRow("utf-16BE") << QFINDTESTDATA("simple_Utf16BE.svg"); + QTest::newRow("utf-32LE") << QFINDTESTDATA("simple_Utf32LE.svg"); + QTest::newRow("utf-32BE") << QFINDTESTDATA("simple_Utf32BE.svg"); +} + +void tst_QSvgPlugin::encodings() +{ + QFETCH(QString, filename); + + { + QFile file(filename); + file.open(QIODevice::ReadOnly); + QVERIFY(QSvgIOHandler::canRead(&file)); + } + + QFile file(filename); + file.open(QIODevice::ReadOnly); + QSvgIOHandler plugin; + plugin.setDevice(&file); + QVERIFY(plugin.canRead()); + QImage img; + QVERIFY(plugin.read(&img)); + QCOMPARE(img.size(), QSize(50, 50)); +} QTEST_MAIN(tst_QSvgPlugin) #include "tst_qsvgplugin.moc" -- 2.35.1