This was created by checking out qtsvg and checking out the kf5
patches from kde.  For more details of those, see
https://dot.kde.org/2021/04/06/announcing-kdes-qt-5-patch-collection

from kde:
 git clone https://invent.kde.org/qt/qt/qtsvg
 cd qtsvg
 git checkout -t origin/5.15
 git format-patch origin/5.15.2..origin/kde/5.15

To update for new patches, git pull and then rerun git format-patch.

Last updated: 2021-01-25

Following patches commented:
patch 01 would create a changes file for 5.12.10
patch 02 already applied
patch 03 would update the version to 5.15.3

In patch 07 binary diffs are used to create some new test svg
files - that part is commented.

Patch 05 is the fix for CVE-2021-3481.

#From e82cf6e005d43be9c49fb3f931433e5d508534f0 Mon Sep 17 00:00:00 2001
#From: Antti Kokko <antti.kokko@qt.io>
#Date: Thu, 15 Oct 2020 09:53:19 +0300
#Subject: [PATCH 01/13] Add changes file for Qt 5.12.10
#
#Change-Id: I08a4c977fe1652853e79ea6ce53b071db72b6986
#Reviewed-by: Robert Loehning <robert.loehning@qt.io>
#(cherry picked from commit 261ed79b966065f4ce398f1a701be6298dd49be9)
#Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
#---
# dist/changes-5.12.10 | 46 ++++++++++++++++++++++++++++++++++++++++++++
# 1 file changed, 46 insertions(+)
# create mode 100644 dist/changes-5.12.10
#
#diff --git a/dist/changes-5.12.10 b/dist/changes-5.12.10
#new file mode 100644
#index 0000000..b8f8f69
#--- /dev/null
#+++ b/dist/changes-5.12.10
#@@ -0,0 +1,46 @@
#+Qt 5.12.10 is a bug-fix release. It maintains both forward and backward
#+compatibility (source and binary) with Qt 5.12.9.
#+
#+For more details, refer to the online documentation included in this
#+distribution. The documentation is also available online:
#+
#+  https://doc.qt.io/qt-5.12/index.html
#+
#+The Qt version 5.12 series is binary compatible with the 5.11.x series.
#+Applications compiled for 5.11 will continue to run with 5.12.
#+
#+Some of the changes listed in this file include issue tracking numbers
#+corresponding to tasks in the Qt Bug Tracker:
#+
#+  https://bugreports.qt.io/
#+
#+Each of these identifiers can be entered in the bug tracker to obtain more
#+information about a particular change.
#+
#+****************************************************************************
#+*                          Library                                         *
#+****************************************************************************
#+
#+ - This release fixes a number of cases where input fuzzing has
#+   revealed that corrupt or pathological input could result in crashes
#+   or undefined behavior:
#+     oss-fuzz-23588
#+     oss-fuzz-23606
#+     oss-fuzz-23633
#+     oss-fuzz-23643
#+     oss-fuzz-23644
#+     oss-fuzz-23731
#+     oss-fuzz-24000
#+     oss-fuzz-24028
#+     oss-fuzz-24131
#+     oss-fuzz-24146
#+     oss-fuzz-24308
#+     oss-fuzz-24611
#+     oss-fuzz-24738
#+
#+Third-Party Code
#+----------------
#+
#+ - XSVG license was re-classified to HPND-sell-variant, "Historical Permission
#+   Notice and Disclaimer - sell variant"
#+
#-- 
#2.33.0
#
#From cb70084b0380db6b34c693821ada4cc44c678bff Mon Sep 17 00:00:00 2001
#From: Antti Kokko <antti.kokko@qt.io>
#Date: Tue, 27 Oct 2020 10:02:11 +0200
#Subject: [PATCH 02/13] Add changes file for Qt 5.15.2
#
#+ ba2477be62b03bb97af13e8c1d51ac6fb5010095 Initialize QSvgHandler with QBuffer instead of QByteArray
#+ cd30c2e9170e4016b29ca0682d733735c8c25bb7 Don't return partially inflated QByteArray
#+ 46c22c4c15b69e5f2f44d3ca308d36dc5f14c6f1 Implement basic format check also for compressed svgs
#+ 73430f7a0393d6d148946ed4b1d2795af3374d9b Avoid recursion when inflating compressed svgs
#- eca805bb2658362f848f34de4742e0ac3148e57c Add changes file for Qt 5.15.1
#+ e3c639e706e6511a2f8511c33f4d265f0717070c Doc: Fix linking to Qt Designer Manual
#+ fdbe89e45c4ef075d0b47ff0d62bbe2ec85e9928 Change classification of XSVG License
#+ 9bb275238f3eb9b8419fa4df5243bb613cb73b4d Bump version
#+ 4433f21a54d1987216b6cd97017a90754103a9d6 Reject corrupt svgs with invalid size
#+ 7dce014c1469f77728bf1ac04b47b9d555189184 Allow loading SVG files with a doctype declaration
#
#Change-Id: If2ec6447c081c389b8513c2710498c41f3aa2266
#Reviewed-by: Andy Shaw <andy.shaw@qt.io>
#(cherry picked from commit 52d3788c7b0116ea3db232dccca5f1e3f1e229ac)
#Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
#---
# dist/changes-5.15.2 | 42 ++++++++++++++++++++++++++++++++++++++++++
# 1 file changed, 42 insertions(+)
# create mode 100644 dist/changes-5.15.2
#
#diff --git a/dist/changes-5.15.2 b/dist/changes-5.15.2
#new file mode 100644
#index 0000000..1fdcd4a
#--- /dev/null
#+++ b/dist/changes-5.15.2
#@@ -0,0 +1,42 @@
#+Qt 5.15.2 is a bug-fix release. It maintains both forward and backward
#+compatibility (source and binary) with Qt 5.15.1.
#+
#+For more details, refer to the online documentation included in this
#+distribution. The documentation is also available online:
#+
#+  https://doc.qt.io/qt-5.15/index.html
#+
#+The Qt version 5.15 series is binary compatible with the 5.14.x series.
#+Applications compiled for 5.14 will continue to run with 5.15.
#+
#+Some of the changes listed in this file include issue tracking numbers
#+corresponding to tasks in the Qt Bug Tracker:
#+
#+  https://bugreports.qt.io/
#+
#+Each of these identifiers can be entered in the bug tracker to obtain more
#+information about a particular change.
#+
#+****************************************************************************
#+*                   Important Behavior Changes                             *
#+****************************************************************************
#+
#+****************************************************************************
#+*                          Library                                         *
#+****************************************************************************
#+
#+ - [QTBUG-87583] Allowed loading SVG files with a doctype declaration
#+ - [oss-fuzz-24611] Implemented a basic format check for compressed svgs so
#+   it will fail early if the file does not start with a svg or xml tag after
#+   decompressing
#+ - [oss-fuzz-24611] Avoids recursion when inflating compressed svgs and no
#+   longer returns a partially extracted QByteArray
#+ - [oss-fuzz-24347] Reduced memory consumption significantly for huge files.
#+ - [oss-fuzz-24735] Reject corrupt svgs with invalid size
#+
#+Third-Party Code
#+----------------
#+
#+ - XSVG license was re-classified to HPND-sell-variant, "Historical Permission
#+   Notice and Disclaimer - sell variant"
#+
#-- 
#2.33.0
#
#From 9aac88424a1b76e0198b52437af58a6d94aff8e9 Mon Sep 17 00:00:00 2001
#From: Jani Heikkinen <jani.heikkinen@qt.io>
#Date: Fri, 6 Nov 2020 11:28:20 +0200
#Subject: [PATCH 03/13] Bump version
#
#Change-Id: Ic1028c7ee449c807933dfc0564052f778026fdea
#---
# .qmake.conf | 2 +-
# 1 file changed, 1 insertion(+), 1 deletion(-)
#
#diff --git a/.qmake.conf b/.qmake.conf
#index ba84e23..bbf484f 100644
#--- a/.qmake.conf
#+++ b/.qmake.conf
#@@ -3,4 +3,4 @@ load(qt_build_config)
# CONFIG += warning_clean
# DEFINES += QT_NO_FOREACH
# 
#-MODULE_VERSION = 5.15.2
#+MODULE_VERSION = 5.15.3
#-- 
#2.33.0
#
From aceea78cc05ac8ff947cee9de8149b48771781a8 Mon Sep 17 00:00:00 2001
From: Eirik Aavitsland <eirik.aavitsland@qt.io>
Date: Tue, 1 Dec 2020 14:39:59 +0100
Subject: [PATCH 04/13] Improve handling of malformed numeric values in svg
 files

Catch cases where the input is not containable in a qreal, and avoid
passing on inf values.

Change-Id: I1ab8932d94473916815385240c29e03afb0e0c9e
Reviewed-by: Robert Loehning <robert.loehning@qt.io>
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 428d56da9d5ed9bda51f7cc3c144996fb3a6a285)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/svg/qsvghandler.cpp | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp
index c937254..b3d9aaf 100644
--- a/src/svg/qsvghandler.cpp
+++ b/src/svg/qsvghandler.cpp
@@ -65,6 +65,7 @@
 #include "private/qmath_p.h"
 
 #include "float.h"
+#include <cmath>
 
 QT_BEGIN_NAMESPACE
 
@@ -672,6 +673,8 @@ static qreal toDouble(const QChar *&str)
             val = -val;
     } else {
         val = QByteArray::fromRawData(temp, pos).toDouble();
+        if (qFpClassify(val) != FP_NORMAL)
+            val = 0;
     }
     return val;
 
-- 
2.33.0

From 95990cbeebc0ab9959e2a925a93ad4897416bbb7 Mon Sep 17 00:00:00 2001
From: Allan Sandfeld Jensen <allan.jensen@qt.io>
Date: Thu, 4 Mar 2021 14:28:48 +0100
Subject: [PATCH 05/13] Clamp parsed doubles to float representable values
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Parts of our rendering assumes incoming doubles can still be sane
floats.

Fixes: QTBUG-91507
Change-Id: I7086a121e1b5ed47695a1251ea90e774dd8f148d
Reviewed-by: Robert Löhning <robert.loehning@qt.io>
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
(cherry picked from commit bfd6ee0d8cf34b63d32adf10ed93daa0086b359f)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/svg/qsvghandler.cpp | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp
index b3d9aaf..9dac05c 100644
--- a/src/svg/qsvghandler.cpp
+++ b/src/svg/qsvghandler.cpp
@@ -673,7 +673,8 @@ static qreal toDouble(const QChar *&str)
             val = -val;
     } else {
         val = QByteArray::fromRawData(temp, pos).toDouble();
-        if (qFpClassify(val) != FP_NORMAL)
+        // Do not tolerate values too wild to be represented normally by floats
+        if (qFpClassify(float(val)) != FP_NORMAL)
             val = 0;
     }
     return val;
@@ -3046,6 +3047,8 @@ static QSvgStyleProperty *createRadialGradientNode(QSvgNode *node,
         ncy = toDouble(cy);
     if (!r.isEmpty())
         nr = toDouble(r);
+    if (nr < 0.5)
+        nr = 0.5;
 
     qreal nfx = ncx;
     if (!fx.isEmpty())
-- 
2.33.0

From 1c2072ad16e0097c15df701dc22f07bf481fc4ec Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Robert=20L=C3=B6hning?= <robert.loehning@qt.io>
Date: Wed, 17 Feb 2021 19:20:42 +0100
Subject: [PATCH 06/13] Avoid buffer overflow in isSupportedSvgFeature

Fixes oss-fuzz issue 29873.

Pick-to: 6.0 6.1
Change-Id: I382683aa2d7d3cf2d05a0b8c41ebf21d032fbd7c
Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
(cherry picked from commit afde7ca3a40f524e40052df696f74190452b22cb)
---
 src/svg/qsvgstructure.cpp | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/src/svg/qsvgstructure.cpp b/src/svg/qsvgstructure.cpp
index b89608b..89c9e4e 100644
--- a/src/svg/qsvgstructure.cpp
+++ b/src/svg/qsvgstructure.cpp
@@ -255,9 +255,13 @@ inline static bool isSupportedSvgFeature(const QString &str)
     };
 
     if (str.length() <= MAX_WORD_LENGTH && str.length() >= MIN_WORD_LENGTH) {
+        const char16_t unicode44 = str.at(44).unicode();
+        const char16_t unicode45 = str.at(45).unicode();
+        if (unicode44 >= sizeof(asso_values) || unicode45 >= sizeof(asso_values))
+            return false;
         const int key = str.length()
-                        + asso_values[str.at(45).unicode()]
-                        + asso_values[str.at(44).unicode()];
+                        + asso_values[unicode45]
+                        + asso_values[unicode44];
         if (key <= MAX_HASH_VALUE && key >= 0)
             return str == QLatin1String(wordlist[key]);
     }
-- 
2.33.0

From cfc616978b52a396b2ef6900546f7fc086d7cab3 Mon Sep 17 00:00:00 2001
From: Eirik Aavitsland <eirik.aavitsland@qt.io>
Date: Thu, 8 Apr 2021 13:19:52 +0200
Subject: [PATCH 07/13] 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 <allan.jensen@qt.io>
(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("<?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 0000000000000000000000000000000000000000..c3312cb2a98dc3a2a7f42100720a94ee913ab641
#GIT binary patch
#literal 228
#zcmY+8!3x4a3`F1AuUP86TPwXt^=FD(h1JSdZ2kG_Y$$>ZBuq%=W%<xD@}kG7o=I|7
#z2JRdw*illcJ7#V~O-GwwcuEfrcxf_~s(bAZ%IGz%b(!VY{DKo3B{>m0F_LN&(W%dt
#i+N`XO_n%MZY8v|_=r&6EzpW7h!FvAF8>RhG#ry&V93m0`
#
#literal 0
#HcmV?d00001

#diff --git a/tests/auto/qsvgplugin/simple_Utf16LE.svg b/tests/auto/qsvgplugin/simple_Utf16LE.svg
#new file mode 100644
#index 0000000000000000000000000000000000000000..cdbeda92a5145faf70fcc8dcdf034141a66f59cf
#GIT binary patch
#literal 228
#zcmY+8!3x4a3`F1AuUP86tCe14^=FD(h1JSdZ2ft4HWWby5+)?`@_7eFp7c1?6It%U
#zz>NbHTWU7yj+rY-)6wQ<9@3pXUYbm`>Q4KEGI~uLT^9Kzzv9SBNsd4#MpjKCI`!F7
#h+lAHf`t#XbLu;Qz-6pC0w>Cl~S}%Wkql6!|Fux@+A`$=q
#
#literal 0
#HcmV?d00001

#diff --git a/tests/auto/qsvgplugin/simple_Utf32BE.svg b/tests/auto/qsvgplugin/simple_Utf32BE.svg
#new file mode 100644
#index 0000000000000000000000000000000000000000..0d5d02c1ba98a60908ca852692bf5f1124d4b64b
#GIT binary patch
#literal 456
#zcmaKnNeV(i3<Z1bDT3}DaU<$w#0i{Gak#u%B^~&<a8V@Pncgeq^)97M;Q}{UL)3gp
#zJcG3@9N_>nXu|-y(68?xK41?!u-Dn_-;iG`C*lNpl{+zUr}+rXy{itj**^qtCjK?`
#zt8ES~h>9K;pbvMMt5J^uzSW*u$K*|4)}Mds?#x;BIj@d@6?oTsl6@WW^k9$VJ7@Kl
#LUi9$m^;`P@=Ncjs
#
#literal 0
#HcmV?d00001

#diff --git a/tests/auto/qsvgplugin/simple_Utf32LE.svg b/tests/auto/qsvgplugin/simple_Utf32LE.svg
#new file mode 100644
#index 0000000000000000000000000000000000000000..58a71596656a79d9540b6bbef92e6b40aec46871
#GIT binary patch
#literal 456
#zcmaKnNeV(i3<b0H6pij3aU=RKBTnFiio@mAD(Jw+g^MET&h*~r9WjrHE8JlNrRFQ*
#z1+4Ah1V>mv7e>&BVSN|k6ArKkd!5bxE%~i-CeC0`c@PtKnoq#oyXsJz{bTTE;$K_8
#z+8XFUspxSD`f!)I8ueJfx7t(dl)UZB`s+{KojI#M=habQ4c_&hWM7XwJ=i1p&RM;s
#K7d`xX&Ds}BU?LI#
#
#literal 0
#HcmV?d00001

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 e1f84f3..73bbe8b 100644
--- a/tests/auto/qsvgplugin/tst_qsvgplugin.cpp
+++ b/tests/auto/qsvgplugin/tst_qsvgplugin.cpp
@@ -61,6 +61,8 @@ private slots:
     void checkSize_data();
     void checkSize();
     void checkImageInclude();
+    void encodings_data();
+    void encodings();
 };
 
 
@@ -145,6 +147,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"
-- 
2.33.0

From 2fca4c537f8e7b11583ea5d7a70b04e39ca99dc1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Robert=20L=C3=B6hning?= <robert.loehning@qt.io>
Date: Fri, 23 Jul 2021 13:53:47 +0200
Subject: [PATCH 08/13] Limit font size to avoid numerous overflows

The font size will be passed through a QFixed in
QFontEngineBox::ascent() and overflow there as well as in further places.

[ChangeLog] Avoid numerous overflows by limiting font size to 0xffff.
This fixes oss-fuzz issue 31701.

Pick-to: 5.15 6.1 6.2
Change-Id: I2d00c5639804af9b056f0efc979e9899c5358cf7
Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
(cherry picked from commit 76eeb072cdffc1a8c776ed01864e6751ccbfba85)
---
 src/svg/qsvghandler.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp
index 9dac05c..e496a54 100644
--- a/src/svg/qsvghandler.cpp
+++ b/src/svg/qsvghandler.cpp
@@ -1384,7 +1384,8 @@ static void parseFont(QSvgNode *node,
             break;
         case FontSizeValue: {
             QSvgHandler::LengthType dummy; // should always be pixel size
-            fontStyle->setSize(parseLength(attributes.fontSize, dummy, handler));
+            fontStyle->setSize(qMin(parseLength(attributes.fontSize, dummy, handler),
+                                    qreal(0xffff)));
         }
             break;
         default:
-- 
2.33.0

From 57c967b24d45cb561a326320590504f1efc2cbfa Mon Sep 17 00:00:00 2001
From: Albert Astals Cid <albert.astals.cid@kdab.com>
Date: Mon, 11 Oct 2021 11:13:57 +0200
Subject: [PATCH 09/13] Support font size not in pixels

Fixes: QTBUG-97422
Pick-to: 6.2
Change-Id: I4df2af0e657f241af69480e6e30d454870df51d8
Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
(cherry picked from commit 4531aad935d55924a32212b339c657ce363a6c08)
---
 src/svg/qsvghandler.cpp | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp
index e496a54..6862494 100644
--- a/src/svg/qsvghandler.cpp
+++ b/src/svg/qsvghandler.cpp
@@ -1383,9 +1383,10 @@ static void parseFont(QSvgNode *node,
         case FontSizeNone:
             break;
         case FontSizeValue: {
-            QSvgHandler::LengthType dummy; // should always be pixel size
-            fontStyle->setSize(qMin(parseLength(attributes.fontSize, dummy, handler),
-                                    qreal(0xffff)));
+            QSvgHandler::LengthType type;
+            qreal fs = parseLength(attributes.fontSize, type, handler);
+            fs = convertToPixels(fs, true, type);
+            fontStyle->setSize(qMin(fs, qreal(0xffff)));
         }
             break;
         default:
-- 
2.33.0

From f00cf42e67119d31fe80ddc37dc275cf2e91d9e0 Mon Sep 17 00:00:00 2001
From: Albert Astals Cid <albert.astals.cid@kdab.com>
Date: Mon, 11 Oct 2021 11:11:26 +0200
Subject: [PATCH 10/13] Fix text x/y when the length is not in pixels

Fixes: QTBUG-97421
Pick-to: 6.2
Change-Id: I41f3cbf8e747530a67fe5074a988ba49aeb43b8e
Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
(cherry picked from commit fc1e1878743bcaac0c81a4748a00d0042cc15815)
---
 src/svg/qsvghandler.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp
index 6862494..ba894bc 100644
--- a/src/svg/qsvghandler.cpp
+++ b/src/svg/qsvghandler.cpp
@@ -3346,7 +3346,9 @@ static QSvgNode *createTextNode(QSvgNode *parent,
     //### editable and rotate not handled
     QSvgHandler::LengthType type;
     qreal nx = parseLength(x, type, handler);
+    nx = convertToPixels(nx, true, type);
     qreal ny = parseLength(y, type, handler);
+    ny = convertToPixels(ny, true, type);
 
     QSvgNode *text = new QSvgText(parent, QPointF(nx, ny));
     return text;
-- 
2.33.0

From 7a98a466bd0a444175ce9a254beed6a185358f6f Mon Sep 17 00:00:00 2001
From: Eirik Aavitsland <eirik.aavitsland@qt.io>
Date: Wed, 7 Jul 2021 10:09:58 +0200
Subject: [PATCH 11/13] Fix parsing of arc elements in paths

The arc element takes some flag parameters, which could be mixed up
with the float parameters since svg does not require delimiting
characters here. Hence legal svg would be misread..

Fixes: QTBUG-92184
Pick-to: 6.2 6.1 5.15
Change-Id: I5885c50d47e2e06ab0f02afefb7a5585c5c713ff
Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
(cherry picked from commit b313862fa04d9a5403c16670a0d911eb3c633ee5)
---
 src/svg/qsvghandler.cpp                      | 19 ++++++++++++++++---
 tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp | 14 ++++++++++++++
 2 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp
index ba894bc..bfacd56 100644
--- a/src/svg/qsvghandler.cpp
+++ b/src/svg/qsvghandler.cpp
@@ -728,15 +728,25 @@ static QVector<qreal> parseNumbersList(const QChar *&str)
     return points;
 }
 
-static inline void parseNumbersArray(const QChar *&str, QVarLengthArray<qreal, 8> &points)
+static inline void parseNumbersArray(const QChar *&str, QVarLengthArray<qreal, 8> &points,
+                                     const char *pattern = nullptr)
 {
+    const size_t patternLen = qstrlen(pattern);
     while (str->isSpace())
         ++str;
     while (isDigit(str->unicode()) ||
            *str == QLatin1Char('-') || *str == QLatin1Char('+') ||
            *str == QLatin1Char('.')) {
 
-        points.append(toDouble(str));
+        if (patternLen && pattern[points.size() % patternLen] == 'f') {
+            // flag expected, may only be 0 or 1
+            if (*str != QLatin1Char('0') && *str != QLatin1Char('1'))
+                return;
+            points.append(*str == QLatin1Char('0') ? 0.0 : 1.0);
+            ++str;
+        } else {
+            points.append(toDouble(str));
+        }
 
         while (str->isSpace())
             ++str;
@@ -1631,8 +1641,11 @@ static bool parsePathDataFast(const QStringRef &dataStr, QPainterPath &path)
         ++str;
         QChar endc = *end;
         *const_cast<QChar *>(end) = 0; // parseNumbersArray requires 0-termination that QStringRef cannot guarantee
+        const char *pattern = nullptr;
+        if (pathElem == QLatin1Char('a') || pathElem == QLatin1Char('A'))
+            pattern = "rrrffrr";
         QVarLengthArray<qreal, 8> arg;
-        parseNumbersArray(str, arg);
+        parseNumbersArray(str, arg, pattern);
         *const_cast<QChar *>(end) = endc;
         if (pathElem == QLatin1Char('z') || pathElem == QLatin1Char('Z'))
             arg.append(0);//dummy
diff --git a/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp b/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp
index 8f1f03b..36c76ec 100644
--- a/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp
+++ b/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp
@@ -74,6 +74,7 @@ private slots:
     void fillRule();
     void opacity();
     void paths();
+    void paths2();
     void displayMode();
     void strokeInherit();
     void testFillInheritance();
@@ -1047,6 +1048,19 @@ void tst_QSvgRenderer::paths()
     }
 }
 
+void tst_QSvgRenderer::paths2()
+{
+    const char *svg =
+        "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\">"
+            "<path d=\"M 3 8 A 5 5 0 1013 8\" id=\"path1\"/>"
+        "</svg>";
+
+    QByteArray data(svg);
+    QSvgRenderer renderer(data);
+    QVERIFY(renderer.isValid());
+    QCOMPARE(renderer.boundsOnElement(QLatin1String("path1")).toRect(), QRect(3, 8, 10, 5));
+}
+
 void tst_QSvgRenderer::displayMode()
 {
     static const char *svgs[] = {
-- 
2.33.0

From 3aa26f02f1ec65c6f8d62267676d5239825c1f1a Mon Sep 17 00:00:00 2001
From: Allan Sandfeld Jensen <allan.jensen@qt.io>
Date: Fri, 5 Mar 2021 12:52:36 +0100
Subject: [PATCH 12/13] Improve parsing of "r"
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Negative r values are illegal, and zero means empty for circles.

Pick-to: 6.1
Change-Id: Icb1d932f35909f71dafe1ee69eb2250eeb1bb2ad
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
(cherry picked from commit 4a88e194e6b243e83703ad83d95e49b2febed99e)
---
 src/svg/qsvghandler.cpp | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp
index bfacd56..9575f14 100644
--- a/src/svg/qsvghandler.cpp
+++ b/src/svg/qsvghandler.cpp
@@ -2585,6 +2585,8 @@ static QSvgNode *createCircleNode(QSvgNode *parent,
     qreal ncx = toDouble(cx);
     qreal ncy = toDouble(cy);
     qreal nr  = toDouble(r);
+    if (nr < 0.0)
+        return nullptr;
 
     QRectF rect(ncx-nr, ncy-nr, nr*2, nr*2);
     QSvgNode *circle = new QSvgCircle(parent, rect);
@@ -3055,15 +3057,16 @@ static QSvgStyleProperty *createRadialGradientNode(QSvgNode *node,
 
     qreal ncx = 0.5;
     qreal ncy = 0.5;
-    qreal nr  = 0.5;
     if (!cx.isEmpty())
         ncx = toDouble(cx);
     if (!cy.isEmpty())
         ncy = toDouble(cy);
+
+    qreal nr = 0.0;
     if (!r.isEmpty())
         nr = toDouble(r);
-    if (nr < 0.5)
-        nr = 0.5;
+    if (nr <= 0.0)
+        return nullptr;
 
     qreal nfx = ncx;
     if (!fx.isEmpty())
-- 
2.33.0

From 24128cdf8bef53eddf31a5709bbbc46293006b1c Mon Sep 17 00:00:00 2001
From: Eirik Aavitsland <eirik.aavitsland@qt.io>
Date: Fri, 2 Jul 2021 16:09:30 +0200
Subject: [PATCH 13/13] Fix parsing of animation clock values

Color animation duration parsing mixed seconds and milliseconds.

Factor out a common function for all clock value parsing, and
add checking for overflow and illegal values as a driveby..

Fixes: QTBUG-94878
Pick-to: 6.2 6.1 5.15
Change-Id: Ie1d974cd2db55a3d65d7ce02c373021021070489
Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
(cherry picked from commit 1da0a668e52994832d8a048772bed65b61cb0e9b)
---
 src/svg/qsvghandler.cpp | 70 ++++++++++++++++++++---------------------
 1 file changed, 35 insertions(+), 35 deletions(-)

diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp
index 9575f14..b542089 100644
--- a/src/svg/qsvghandler.cpp
+++ b/src/svg/qsvghandler.cpp
@@ -2373,6 +2373,27 @@ static bool parseAnimateNode(QSvgNode *parent,
     return true;
 }
 
+static int parseClockValue(QString str, bool *ok)
+{
+    int res = 0;
+    int ms = 1000;
+    str = str.trimmed();
+    if (str.endsWith(QLatin1String("ms"))) {
+        str.chop(2);
+        ms = 1;
+    } else if (str.endsWith(QLatin1String("s"))) {
+        str.chop(1);
+    }
+    double val = ms * toDouble(str, ok);
+    if (ok) {
+        if (val > std::numeric_limits<int>::min() && val < std::numeric_limits<int>::max())
+            res = static_cast<int>(val);
+        else
+            *ok = false;
+    }
+    return res;
+}
+
 static bool parseAnimateColorNode(QSvgNode *parent,
                                   const QXmlStreamAttributes &attributes,
                                   QSvgHandler *handler)
@@ -2406,23 +2427,13 @@ static bool parseAnimateColorNode(QSvgNode *parent,
         }
     }
 
-    int ms = 1000;
-    beginStr = beginStr.trimmed();
-    if (beginStr.endsWith(QLatin1String("ms"))) {
-        beginStr.chop(2);
-        ms = 1;
-    } else if (beginStr.endsWith(QLatin1String("s"))) {
-        beginStr.chop(1);
-    }
-    durStr = durStr.trimmed();
-    if (durStr.endsWith(QLatin1String("ms"))) {
-        durStr.chop(2);
-        ms = 1;
-    } else if (durStr.endsWith(QLatin1String("s"))) {
-        durStr.chop(1);
-    }
-    int begin = static_cast<int>(toDouble(beginStr) * ms);
-    int end   = static_cast<int>((toDouble(durStr) + begin) * ms);
+    bool ok = true;
+    int begin = parseClockValue(beginStr, &ok);
+    if (!ok)
+        return false;
+    int end = begin + parseClockValue(durStr, &ok);
+    if (!ok || end <= begin)
+        return false;
 
     QSvgAnimateColor *anim = new QSvgAnimateColor(begin, end, 0);
     anim->setArgs((targetStr == QLatin1String("fill")), colors);
@@ -2512,24 +2523,13 @@ static bool parseAnimateTransformNode(QSvgNode *parent,
         }
     }
 
-    int ms = 1000;
-    beginStr = beginStr.trimmed();
-    if (beginStr.endsWith(QLatin1String("ms"))) {
-        beginStr.chop(2);
-        ms = 1;
-    } else if (beginStr.endsWith(QLatin1String("s"))) {
-        beginStr.chop(1);
-    }
-    int begin = static_cast<int>(toDouble(beginStr) * ms);
-    durStr = durStr.trimmed();
-    if (durStr.endsWith(QLatin1String("ms"))) {
-        durStr.chop(2);
-        ms = 1;
-    } else if (durStr.endsWith(QLatin1String("s"))) {
-        durStr.chop(1);
-        ms = 1000;
-    }
-    int end = static_cast<int>(toDouble(durStr)*ms) + begin;
+    bool ok = true;
+    int begin = parseClockValue(beginStr, &ok);
+    if (!ok)
+        return false;
+    int end = begin + parseClockValue(durStr, &ok);
+    if (!ok || end <= begin)
+        return false;
 
     QSvgAnimateTransform::TransformType type = QSvgAnimateTransform::Empty;
     if (typeStr == QLatin1String("translate")) {
-- 
2.33.0

From 5b9285c34731e67f9f1d61ec804740991f2a0380 Mon Sep 17 00:00:00 2001
From: Eirik Aavitsland <eirik.aavitsland@qt.io>
Date: Mon, 25 Oct 2021 14:17:55 +0200
Subject: [PATCH 14/16] Do stricter error checking when parsing path nodes
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The SVG spec mandates that path parsing should terminate on the first
error encountered, and an error be reported. To improve the handling
of corrupt files, implement such error handling, and also limit the
number of QPainterPath elements to a reasonable range.

Fixes: QTBUG-96044
Pick-to: 6.2 5.15 5.12
Change-Id: Ic5e65d6b658516d6f1317c72de365c8c7ad81891
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Reviewed-by: Robert Löhning <robert.loehning@qt.io>
(cherry picked from commit 36cfd9efb9b22b891adee9c48d30202289cfa620)
---
 src/svg/qsvghandler.cpp | 59 +++++++++++++++++------------------------
 1 file changed, 25 insertions(+), 34 deletions(-)

diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp
index b542089..2ea80ed 100644
--- a/src/svg/qsvghandler.cpp
+++ b/src/svg/qsvghandler.cpp
@@ -1627,6 +1627,7 @@ static void pathArc(QPainterPath &path,
 
 static bool parsePathDataFast(const QStringRef &dataStr, QPainterPath &path)
 {
+    const int maxElementCount = 0x7fff; // Assume file corruption if more path elements than this
     qreal x0 = 0, y0 = 0;              // starting point
     qreal x = 0, y = 0;                // current point
     char lastMode = 0;
@@ -1634,7 +1635,8 @@ static bool parsePathDataFast(const QStringRef &dataStr, QPainterPath &path)
     const QChar *str = dataStr.constData();
     const QChar *end = str + dataStr.size();
 
-    while (str != end) {
+    bool ok = true;
+    while (ok && str != end) {
         while (str->isSpace() && (str + 1) != end)
             ++str;
         QChar pathElem = *str;
@@ -1651,14 +1653,13 @@ static bool parsePathDataFast(const QStringRef &dataStr, QPainterPath &path)
             arg.append(0);//dummy
         const qreal *num = arg.constData();
         int count = arg.count();
-        while (count > 0) {
+        while (ok && count > 0) {
             qreal offsetX = x;        // correction offsets
             qreal offsetY = y;        // for relative commands
             switch (pathElem.unicode()) {
             case 'm': {
                 if (count < 2) {
-                    num++;
-                    count--;
+                    ok = false;
                     break;
                 }
                 x = x0 = num[0] + offsetX;
@@ -1675,8 +1676,7 @@ static bool parsePathDataFast(const QStringRef &dataStr, QPainterPath &path)
                 break;
             case 'M': {
                 if (count < 2) {
-                    num++;
-                    count--;
+                    ok = false;
                     break;
                 }
                 x = x0 = num[0];
@@ -1702,8 +1702,7 @@ static bool parsePathDataFast(const QStringRef &dataStr, QPainterPath &path)
                 break;
             case 'l': {
                 if (count < 2) {
-                    num++;
-                    count--;
+                    ok = false;
                     break;
                 }
                 x = num[0] + offsetX;
@@ -1716,8 +1715,7 @@ static bool parsePathDataFast(const QStringRef &dataStr, QPainterPath &path)
                 break;
             case 'L': {
                 if (count < 2) {
-                    num++;
-                    count--;
+                    ok = false;
                     break;
                 }
                 x = num[0];
@@ -1757,8 +1755,7 @@ static bool parsePathDataFast(const QStringRef &dataStr, QPainterPath &path)
                 break;
             case 'c': {
                 if (count < 6) {
-                    num += count;
-                    count = 0;
+                    ok = false;
                     break;
                 }
                 QPointF c1(num[0] + offsetX, num[1] + offsetY);
@@ -1774,8 +1771,7 @@ static bool parsePathDataFast(const QStringRef &dataStr, QPainterPath &path)
             }
             case 'C': {
                 if (count < 6) {
-                    num += count;
-                    count = 0;
+                    ok = false;
                     break;
                 }
                 QPointF c1(num[0], num[1]);
@@ -1791,8 +1787,7 @@ static bool parsePathDataFast(const QStringRef &dataStr, QPainterPath &path)
             }
             case 's': {
                 if (count < 4) {
-                    num += count;
-                    count = 0;
+                    ok = false;
                     break;
                 }
                 QPointF c1;
@@ -1813,8 +1808,7 @@ static bool parsePathDataFast(const QStringRef &dataStr, QPainterPath &path)
             }
             case 'S': {
                 if (count < 4) {
-                    num += count;
-                    count = 0;
+                    ok = false;
                     break;
                 }
                 QPointF c1;
@@ -1835,8 +1829,7 @@ static bool parsePathDataFast(const QStringRef &dataStr, QPainterPath &path)
             }
             case 'q': {
                 if (count < 4) {
-                    num += count;
-                    count = 0;
+                    ok = false;
                     break;
                 }
                 QPointF c(num[0] + offsetX, num[1] + offsetY);
@@ -1851,8 +1844,7 @@ static bool parsePathDataFast(const QStringRef &dataStr, QPainterPath &path)
             }
             case 'Q': {
                 if (count < 4) {
-                    num += count;
-                    count = 0;
+                    ok = false;
                     break;
                 }
                 QPointF c(num[0], num[1]);
@@ -1867,8 +1859,7 @@ static bool parsePathDataFast(const QStringRef &dataStr, QPainterPath &path)
             }
             case 't': {
                 if (count < 2) {
-                    num += count;
-                    count = 0;
+                    ok = false;
                     break;
                 }
                 QPointF e(num[0] + offsetX, num[1] + offsetY);
@@ -1888,8 +1879,7 @@ static bool parsePathDataFast(const QStringRef &dataStr, QPainterPath &path)
             }
             case 'T': {
                 if (count < 2) {
-                    num += count;
-                    count = 0;
+                    ok = false;
                     break;
                 }
                 QPointF e(num[0], num[1]);
@@ -1909,8 +1899,7 @@ static bool parsePathDataFast(const QStringRef &dataStr, QPainterPath &path)
             }
             case 'a': {
                 if (count < 7) {
-                    num += count;
-                    count = 0;
+                    ok = false;
                     break;
                 }
                 qreal rx = (*num++);
@@ -1932,8 +1921,7 @@ static bool parsePathDataFast(const QStringRef &dataStr, QPainterPath &path)
                 break;
             case 'A': {
                 if (count < 7) {
-                    num += count;
-                    count = 0;
+                    ok = false;
                     break;
                 }
                 qreal rx = (*num++);
@@ -1954,12 +1942,15 @@ static bool parsePathDataFast(const QStringRef &dataStr, QPainterPath &path)
             }
                 break;
             default:
-                return false;
+                ok = false;
+                break;
             }
             lastMode = pathElem.toLatin1();
+            if (path.elementCount() > maxElementCount)
+                ok = false;
         }
     }
-    return true;
+    return ok;
 }
 
 static bool parseStyle(QSvgNode *node,
@@ -2997,8 +2988,8 @@ static QSvgNode *createPathNode(QSvgNode *parent,
 
     QPainterPath qpath;
     qpath.setFillRule(Qt::WindingFill);
-    //XXX do error handling
-    parsePathDataFast(data, qpath);
+    if (!parsePathDataFast(data, qpath))
+        qCWarning(lcSvgHandler, "Invalid path data; path truncated.");
 
     QSvgNode *path = new QSvgPath(parent, qpath);
     return path;
-- 
2.33.0

From 0cb681eacca0f757702fa409bb05d3d3650aba4e Mon Sep 17 00:00:00 2001
From: Eirik Aavitsland <eirik.aavitsland@qt.io>
Date: Mon, 25 Oct 2021 14:43:09 +0200
Subject: [PATCH 15/16] SVG Image reading: Reject oversize svgs as corrupt
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Add an upper limit for height and width at 0xffff, same as jpeg.

Fixes: QTBUG-95891
Pick-to: 6.2 5.15 5.12
Change-Id: I0dbc80dab3aab9b4743548772fb63fa69ea21f8a
Reviewed-by: Robert Löhning <robert.loehning@qt.io>
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit e544d8e457d52b543cae5c988f81237c7d6608da)

asturmlechner 2022-01-03: resolve conflict with preceding dev branch
  commit 0003ec68e9925a8386eb055e0030fe7f270aa56f.
---
 src/plugins/imageformats/svg/qsvgiohandler.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/plugins/imageformats/svg/qsvgiohandler.cpp b/src/plugins/imageformats/svg/qsvgiohandler.cpp
index 4136aaf..fd3529a 100644
--- a/src/plugins/imageformats/svg/qsvgiohandler.cpp
+++ b/src/plugins/imageformats/svg/qsvgiohandler.cpp
@@ -189,6 +189,8 @@ bool QSvgIOHandler::read(QImage *image)
             }
         }
         if (!finalSize.isEmpty()) {
+            if (qMax(finalSize.width(), finalSize.height()) > 0xffff)
+                return false; // Assume corrupted file
             image->fill(d->backColor.rgba());
             QPainter p(image);
             d->r.render(&p, bounds);
-- 
2.33.0

From 728012f7762ecd5762d493f8796907c6456f31e7 Mon Sep 17 00:00:00 2001
From: Eirik Aavitsland <eirik.aavitsland@qt.io>
Date: Wed, 5 Jan 2022 09:48:22 +0100
Subject: [PATCH 16/16] Unconditionally stop parsing after the svg end tag
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

A QSvghandler may be created either with an external QXmlStreamReader
object, or with a bytearray/iodevice, in which case it will create its
own stream reader. The check to end parisng at the </svg> tag was
active only in the first case. This could result in different behavior
when reading an svg image from file vs. reading it from a bytearray
or resource.

Fixes: QTBUG-99407
Pick-to: 6.3 6.2 5.15
Change-Id: I187b39256f2b16ea952a3ae1b77c067ff96e4155
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Reviewed-by: Robert Löhning <robert.loehning@qt.io>
(cherry picked from commit 1749388cdc765fca4206aaf0f84ac9b0877dfc9a)
---
 src/svg/qsvghandler.cpp | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp
index 2ea80ed..f2653af 100644
--- a/src/svg/qsvghandler.cpp
+++ b/src/svg/qsvghandler.cpp
@@ -3696,9 +3696,7 @@ void QSvgHandler::parse()
         case QXmlStreamReader::EndElement:
             endElement(xml->name());
             ++remainingUnfinishedElements;
-            // if we are using somebody else's qxmlstreamreader
-            // we should not read until the end of the stream
-            done = !m_ownsReader && (xml->name() == QLatin1String("svg"));
+            done = (xml->name() == QLatin1String("svg"));
             break;
         case QXmlStreamReader::Characters:
             characters(xml->text());
-- 
2.33.0

