summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEirik Aavitsland <eirik.aavitsland@qt.io>2021-04-08 13:19:52 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2021-04-08 20:08:06 +0000
commite0dd65ea8584f006281e931de041b79b16de0cf4 (patch)
treeff01fe33e22cc8459cdadfd7104770bd4f87cb71
parent432a45ec123a22fc1f458475f99b99364459e07d (diff)
downloadqtsvg-e0dd65ea8584f006281e931de041b79b16de0cf4.tar.gz
Make image handler accept UTF-16/UTF-32 encoded SVGs
The canRead() header checks assumed 8 bit encoding. Fixes: QTBUG-90744 Change-Id: Ibe934fe9ed31b89ee0fbfc4562aa66ab1b359225 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io> (cherry picked from commit 45fb1f07eaa984af40fca9f12b8f3d27f7b0e9ac) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--src/plugins/imageformats/svg/qsvgiohandler.cpp37
-rw-r--r--tests/auto/qsvgplugin/simple_Utf16BE.svgbin0 -> 228 bytes
-rw-r--r--tests/auto/qsvgplugin/simple_Utf16LE.svgbin0 -> 228 bytes
-rw-r--r--tests/auto/qsvgplugin/simple_Utf32BE.svgbin0 -> 456 bytes
-rw-r--r--tests/auto/qsvgplugin/simple_Utf32LE.svgbin0 -> 456 bytes
-rw-r--r--tests/auto/qsvgplugin/simple_Utf8.svg3
-rw-r--r--tests/auto/qsvgplugin/tst_qsvgplugin.cpp32
7 files changed, 57 insertions, 15 deletions
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("<?xml") || ba.startsWith("<svg") || ba.startsWith("<!--") || ba.startsWith("<!DOCTYPE svg");
+}
bool QSvgIOHandler::canRead() const
{
@@ -126,15 +144,9 @@ bool QSvgIOHandler::canRead() const
if (d->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("<?xml") || buf.contains("<svg") || buf.contains("<!--") || buf.contains("<!DOCTYPE svg")) {
- setFormat("svg");
+ bool isCompressed = false;
+ if (isPossiblySvg(device(), &isCompressed)) {
+ setFormat(isCompressed ? "svgz" : "svg");
return true;
}
return false;
@@ -260,12 +272,7 @@ bool QSvgIOHandler::supportsOption(ImageOption option) const
bool QSvgIOHandler::canRead(QIODevice *device)
{
- QByteArray buf = device->peek(16);
- return
-#ifndef QT_NO_COMPRESS
- buf.startsWith("\x1f\x8b") ||
-#endif
- buf.contains("<?xml") || buf.contains("<svg") || buf.contains("<!--") || buf.contains("<!DOCTYPE svg");
+ return isPossiblySvg(device);
}
QT_END_NAMESPACE
diff --git a/tests/auto/qsvgplugin/simple_Utf16BE.svg b/tests/auto/qsvgplugin/simple_Utf16BE.svg
new file mode 100644
index 0000000..c3312cb
--- /dev/null
+++ b/tests/auto/qsvgplugin/simple_Utf16BE.svg
Binary files differ
diff --git a/tests/auto/qsvgplugin/simple_Utf16LE.svg b/tests/auto/qsvgplugin/simple_Utf16LE.svg
new file mode 100644
index 0000000..cdbeda9
--- /dev/null
+++ b/tests/auto/qsvgplugin/simple_Utf16LE.svg
Binary files differ
diff --git a/tests/auto/qsvgplugin/simple_Utf32BE.svg b/tests/auto/qsvgplugin/simple_Utf32BE.svg
new file mode 100644
index 0000000..0d5d02c
--- /dev/null
+++ b/tests/auto/qsvgplugin/simple_Utf32BE.svg
Binary files differ
diff --git a/tests/auto/qsvgplugin/simple_Utf32LE.svg b/tests/auto/qsvgplugin/simple_Utf32LE.svg
new file mode 100644
index 0000000..58a7159
--- /dev/null
+++ b/tests/auto/qsvgplugin/simple_Utf32LE.svg
Binary files differ
diff --git a/tests/auto/qsvgplugin/simple_Utf8.svg b/tests/auto/qsvgplugin/simple_Utf8.svg
new file mode 100644
index 0000000..2052c48
--- /dev/null
+++ b/tests/auto/qsvgplugin/simple_Utf8.svg
@@ -0,0 +1,3 @@
+<svg version="1.0" xmlns="http://www.w3.org/2000/svg">
+ <circle cx="50" cy="50" r="25" fill="#00ff00" />
+</svg>
diff --git a/tests/auto/qsvgplugin/tst_qsvgplugin.cpp b/tests/auto/qsvgplugin/tst_qsvgplugin.cpp
index 95f37eb..927e73f 100644
--- a/tests/auto/qsvgplugin/tst_qsvgplugin.cpp
+++ b/tests/auto/qsvgplugin/tst_qsvgplugin.cpp
@@ -60,6 +60,8 @@ private slots:
void checkSize_data();
void checkSize();
void checkImageInclude();
+ void encodings_data();
+ void encodings();
};
@@ -144,6 +146,36 @@ void tst_QSvgPlugin::checkImageInclude()
logMessages.clear();
}
+void tst_QSvgPlugin::encodings_data()
+{
+ QTest::addColumn<QString>("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"