public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
From: "Andreas Sturmlechner" <asturm@gentoo.org>
To: gentoo-commits@lists.gentoo.org
Subject: [gentoo-commits] repo/gentoo:master commit in: dev-qt/qtxml/files/, dev-qt/qtxml/
Date: Mon, 07 Apr 2025 17:32:59 +0000 (UTC)	[thread overview]
Message-ID: <1744047150.c0a1cb6be7b1cb44f4e9751438141ce78d56b0d5.asturm@gentoo> (raw)

commit:     c0a1cb6be7b1cb44f4e9751438141ce78d56b0d5
Author:     Andreas Sturmlechner <asturm <AT> gentoo <DOT> org>
AuthorDate: Mon Apr  7 17:28:00 2025 +0000
Commit:     Andreas Sturmlechner <asturm <AT> gentoo <DOT> org>
CommitDate: Mon Apr  7 17:32:30 2025 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=c0a1cb6b

dev-qt/qtxml: Fix CVE-2025-30348

See also:
https://www.qt.io/blog/security-advisory-dos-qt-xml-qdom

Signed-off-by: Andreas Sturmlechner <asturm <AT> gentoo.org>

 .../qtxml/files/qtxml-5.15.16-CVE-2025-30348.patch | 156 +++++++++++++++++++++
 dev-qt/qtxml/qtxml-5.15.16-r1.ebuild               |  31 ++++
 2 files changed, 187 insertions(+)

diff --git a/dev-qt/qtxml/files/qtxml-5.15.16-CVE-2025-30348.patch b/dev-qt/qtxml/files/qtxml-5.15.16-CVE-2025-30348.patch
new file mode 100644
index 000000000000..bbc001a77d40
--- /dev/null
+++ b/dev-qt/qtxml/files/qtxml-5.15.16-CVE-2025-30348.patch
@@ -0,0 +1,156 @@
+From 16918c1df3e709df2a97281e3825d94c84edb668 Mon Sep 17 00:00:00 2001
+From: Christian Ehrlicher <ch.ehrlicher@gmx.de>
+Date: Tue, 06 Aug 2024 22:39:44 +0200
+Subject: [PATCH] XML/QDom: speedup encodeText()
+
+The code copied the whole string, then replaced parts inline, at
+the cost of relocating everything beyond, at each replacement.
+Instead, copy character by character (in chunks where possible)
+and append replacements as we skip what they replace.
+
+Manual conflict resolution for 6.5:
+- This is a manual cherry-pick. The original change was only
+  picked to 6.8, but the quadratic behavior is present in Qt 5, too.
+- Changed Task-number to Fixes: because this is the real fix;
+  the QString change, 315210de916d060c044c01e53ff249d676122b1b,
+  was unrelated to the original QTBUG-127549.
+
+Manual conflcit resolution for 5.15:
+- Kept/re-added QTextCodec::canEncode() check
+- Ported from Qt 6 to 5, to wit:
+  - qsizetype -> int
+  - QStringView::first/sliced(n) -> left/mid(n)
+    (these functions are clearly called in-range, so the widened
+    contract of the Qt 5 functions doesn't matter)
+- Ported from C++17- and C++14-isms to C++11:
+  - replaced polymorphic lambda with a normal one (this requires
+    rewriting the !canEncode() branch to use QByteArray/QLatin1String
+    instead of QString)
+- As a drive-by, corrected the indentation of the case labels to
+  horizontally align existing code (and follow Qt style)
+
+Fixes: QTBUG-127549
+Change-Id: I368482859ed0c4127f1eec2919183711b5488ada
+Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
+(cherry picked from commit 2ce08e3671b8d18b0284447e5908ce15e6e8f80f)
+Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
+(cherry picked from commit 225e235cf966a44af23dbe9aaaa2fd20ab6430ee)
+Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
+(cherry picked from commit 905a5bd421efff6a1d90b6140500d134d32ca745)
+---
+
+diff --git a/src/xml/dom/qdom.cpp b/src/xml/dom/qdom.cpp
+index 872221c..bf70477 100644
+--- a/src/xml/dom/qdom.cpp
++++ b/src/xml/dom/qdom.cpp
+@@ -3676,59 +3676,67 @@
+     const QTextCodec *const codec = s.codec();
+     Q_ASSERT(codec);
+ #endif
+-    QString retval(str);
+-    int len = retval.length();
+-    int i = 0;
++    QString retval;
++    int start = 0;
++    auto appendToOutput = [&](int cur, QLatin1String replacement)
++    {
++        if (start < cur) {
++            retval.reserve(str.size() + replacement.size());
++            retval.append(QStringView(str).left(cur).mid(start));
++        }
++        // Skip over str[cur], replaced by replacement
++        start = cur + 1;
++        retval.append(replacement);
++    };
+ 
+-    while (i < len) {
+-        const QChar ati(retval.at(i));
+-
+-        if (ati == QLatin1Char('<')) {
+-            retval.replace(i, 1, QLatin1String("&lt;"));
+-            len += 3;
+-            i += 4;
+-        } else if (encodeQuotes && (ati == QLatin1Char('"'))) {
+-            retval.replace(i, 1, QLatin1String("&quot;"));
+-            len += 5;
+-            i += 6;
+-        } else if (ati == QLatin1Char('&')) {
+-            retval.replace(i, 1, QLatin1String("&amp;"));
+-            len += 4;
+-            i += 5;
+-        } else if (ati == QLatin1Char('>') && i >= 2 && retval[i - 1] == QLatin1Char(']') && retval[i - 2] == QLatin1Char(']')) {
+-            retval.replace(i, 1, QLatin1String("&gt;"));
+-            len += 3;
+-            i += 4;
+-        } else if (performAVN &&
+-                   (ati == QChar(0xA) ||
+-                    ati == QChar(0xD) ||
+-                    ati == QChar(0x9))) {
+-            const QString replacement(QLatin1String("&#x") + QString::number(ati.unicode(), 16) + QLatin1Char(';'));
+-            retval.replace(i, 1, replacement);
+-            i += replacement.length();
+-            len += replacement.length() - 1;
+-        } else if (encodeEOLs && ati == QChar(0xD)) {
+-            retval.replace(i, 1, QLatin1String("&#xd;")); // Replace a single 0xD with a ref for 0xD
+-            len += 4;
+-            i += 5;
+-        } else {
++    const int len = str.size();
++    for (int cur = 0; cur < len; ++cur) {
++        switch (const char16_t ati = str[cur].unicode()) {
++        case u'<':
++            appendToOutput(cur, QLatin1String("&lt;"));
++            break;
++        case u'"':
++            if (encodeQuotes)
++                appendToOutput(cur, QLatin1String("&quot;"));
++            break;
++        case u'&':
++            appendToOutput(cur, QLatin1String("&amp;"));
++            break;
++        case u'>':
++            if (cur >= 2 && str[cur - 1] == u']' && str[cur - 2] == u']')
++                appendToOutput(cur, QLatin1String("&gt;"));
++            break;
++        case u'\r':
++            if (performAVN || encodeEOLs)
++                appendToOutput(cur, QLatin1String("&#xd;"));    // \r == 0x0d
++            break;
++        case u'\n':
++            if (performAVN)
++                appendToOutput(cur, QLatin1String("&#xa;"));    // \n == 0x0a
++            break;
++        case u'\t':
++            if (performAVN)
++                appendToOutput(cur, QLatin1String("&#x9;"));    // \t == 0x09
++            break;
++        default:
+ #if QT_CONFIG(textcodec)
+             if(codec->canEncode(ati))
+-                ++i;
++                ; // continue
+             else
+ #endif
+             {
+                 // We have to use a character reference to get it through.
+-                const ushort codepoint(ati.unicode());
+-                const QString replacement(QLatin1String("&#x") + QString::number(codepoint, 16) + QLatin1Char(';'));
+-                retval.replace(i, 1, replacement);
+-                i += replacement.length();
+-                len += replacement.length() - 1;
++                const QByteArray replacement = "&#x" + QByteArray::number(uint{ati}, 16) + ';';
++                appendToOutput(cur, QLatin1String{replacement});
+             }
++            break;
+         }
+     }
+-
+-    return retval;
++    if (start > 0) {
++        retval.append(QStringView(str).left(len).mid(start));
++        return retval;
++    }
++    return str;
+ }
+ 
+ void QDomAttrPrivate::save(QTextStream& s, int, int) const

diff --git a/dev-qt/qtxml/qtxml-5.15.16-r1.ebuild b/dev-qt/qtxml/qtxml-5.15.16-r1.ebuild
new file mode 100644
index 000000000000..d94919409abc
--- /dev/null
+++ b/dev-qt/qtxml/qtxml-5.15.16-r1.ebuild
@@ -0,0 +1,31 @@
+# Copyright 1999-2025 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+if [[ ${PV} != *9999* ]]; then
+	QT5_KDEPATCHSET_REV=1
+	KEYWORDS="~amd64 ~arm ~arm64 ~hppa ~loong ~ppc ~ppc64 ~riscv ~x86"
+fi
+
+QT5_MODULE="qtbase"
+inherit qt5-build
+
+DESCRIPTION="Implementation of SAX and DOM for the Qt5 framework"
+
+IUSE=""
+
+RDEPEND="=dev-qt/qtcore-${QT5_PV}*:5="
+DEPEND="${RDEPEND}
+	test? ( =dev-qt/qtnetwork-${QT5_PV}* )
+"
+
+QT5_TARGET_SUBDIRS=(
+	src/xml
+)
+
+QT5_GENTOO_PRIVATE_CONFIG=(
+	:xml
+)
+
+PATCHES=( "${FILESDIR}/${P}-CVE-2025-30348.patch" )


                 reply	other threads:[~2025-04-07 17:33 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1744047150.c0a1cb6be7b1cb44f4e9751438141ce78d56b0d5.asturm@gentoo \
    --to=asturm@gentoo.org \
    --cc=gentoo-commits@lists.gentoo.org \
    --cc=gentoo-dev@lists.gentoo.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox