Your message dated Sat, 29 Jun 2024 10:47:47 +0000
with message-id <e1snvcr-002brz...@coccia.debian.org>
and subject line Released with 11.10
has caused the Debian Bug report #1070154,
regarding bullseye-pu: qtbase-opensource-src/5.15.2+dfsg-9+deb11u1
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact ow...@bugs.debian.org
immediately.)


-- 
1070154: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1070154
Debian Bug Tracking System
Contact ow...@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
Tags: bullseye
User: release.debian....@packages.debian.org
Usertags: pu


The attached debdiff for qtbase-opensource-src fixes several CVEs in Bullseye. All CVEs are marked as no-dsa by the security team.

  Thorsten
diff -Nru qtbase-opensource-src-5.15.2+dfsg/debian/changelog 
qtbase-opensource-src-5.15.2+dfsg/debian/changelog
--- qtbase-opensource-src-5.15.2+dfsg/debian/changelog  2021-07-02 
17:58:04.000000000 +0200
+++ qtbase-opensource-src-5.15.2+dfsg/debian/changelog  2024-04-28 
22:48:02.000000000 +0200
@@ -1,3 +1,33 @@
+qtbase-opensource-src (5.15.2+dfsg-9+deb11u1) bullseye; urgency=medium
+
+  * Non-maintainer upload by the LTS Team.
+  * CVE-2024-25580 (Closes: #1064053)
+    fix buffer overflow due to crafted KTX image file
+  * CVE-2023-32763 (Closes: #1036702)
+    fix QTextLayout buffer overflow due to crafted SVG file
+  * CVE-2022-25255
+    prevent QProcess from execution of a binary from the current working
+    directory when not found in the PATH
+  * CVE-2023-24607 (Closes: #1031872)
+    fix denial of service via a crafted string when the SQL ODBC driver
+    plugin is used
+  * fix regression caused by patch for CVE-2023-24607
+  * CVE-2023-32762
+    prevent incorrect parsing of the strict-transport-security (HSTS) header
+  * CVE-2023-51714 (Closes: #1060694)
+    fix incorrect HPack integer overflow check.
+  * CVE-2023-38197 (Closes: #1041105)
+    fix infinite loop in recursive entity expansion
+  * CVE-2023-37369 (Closes: #1059302)
+    fix crash of application in QXmlStreamReader due to crafted XML string
+  * CVE-2023-34410 (Closes: #1037210)
+    fix checking during TLS whether root of the chain really is a
+    configured CA certificate
+  * CVE-2023-33285 (Closes: #1036848)
+    fix buffer overflow in QDnsLookup
+
+ -- Thorsten Alteholz <deb...@alteholz.de>  Sun, 28 Apr 2024 22:48:02 +0200
+
 qtbase-opensource-src (5.15.2+dfsg-9) unstable; urgency=medium
 
   * Revert adding fix-misplacement-of-placeholder-text-in-QLineEdit.diff.
diff -Nru qtbase-opensource-src-5.15.2+dfsg/debian/patches/CVE-2022-25255.diff 
qtbase-opensource-src-5.15.2+dfsg/debian/patches/CVE-2022-25255.diff
--- qtbase-opensource-src-5.15.2+dfsg/debian/patches/CVE-2022-25255.diff        
1970-01-01 01:00:00.000000000 +0100
+++ qtbase-opensource-src-5.15.2+dfsg/debian/patches/CVE-2022-25255.diff        
2024-03-05 13:22:01.000000000 +0100
@@ -0,0 +1,96 @@
+Description: QProcess: ensure we don't accidentally execute something from CWD
+ Unless "." (or the empty string) is in $PATH, we're not supposed to find
+ executables in the current directory. This is how the Unix shells behave
+ and we match their behavior. It's also the behavior Qt had prior to 5.9
+ (commit 28666d167aa8e602c0bea25ebc4d51b55005db13). On Windows, searching
+ the current directory is the norm, so we keep that behavior.
+ .
+ This commit does not add an explicit check for an empty return from
+ QStandardPaths::findExecutable(). Instead, we allow that empty string to
+ go all the way to execve(2), which will fail with ENOENT. We could catch
+ it early, before fork(2), but why add code for the error case?
+ .
+ See https://kde.org/info/security/advisory-20220131-1.txt
+Origin: upstream, 
https://download.qt.io/official_releases/qt/5.15/CVE-2022-25255-qprocess5-15.diff
+Last-Update: 2022-02-21
+
+Index: qtbase-opensource-src-5.15.2+dfsg/src/corelib/io/qprocess_unix.cpp
+===================================================================
+--- qtbase-opensource-src-5.15.2+dfsg.orig/src/corelib/io/qprocess_unix.cpp    
2024-03-05 13:21:06.432881985 +0100
++++ qtbase-opensource-src-5.15.2+dfsg/src/corelib/io/qprocess_unix.cpp 
2024-03-05 13:21:06.428881981 +0100
+@@ -1,7 +1,7 @@
+ /****************************************************************************
+ **
+ ** Copyright (C) 2016 The Qt Company Ltd.
+-** Copyright (C) 2016 Intel Corporation.
++** Copyright (C) 2022 Intel Corporation.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the QtCore module of the Qt Toolkit.
+@@ -422,14 +422,15 @@
+     // Add the program name to the argument list.
+     argv[0] = nullptr;
+     if (!program.contains(QLatin1Char('/'))) {
++        // findExecutable() returns its argument if it's an absolute path,
++        // otherwise it searches $PATH; returns empty if not found (we handle
++        // that case much later)
+         const QString &exeFilePath = QStandardPaths::findExecutable(program);
+-        if (!exeFilePath.isEmpty()) {
+-            const QByteArray &tmp = QFile::encodeName(exeFilePath);
+-            argv[0] = ::strdup(tmp.constData());
+-        }
+-    }
+-    if (!argv[0])
++        const QByteArray &tmp = QFile::encodeName(exeFilePath);
++        argv[0] = ::strdup(tmp.constData());
++    } else {
+         argv[0] = ::strdup(encodedProgramName.constData());
++    }
+ 
+     // Add every argument to the list
+     for (int i = 0; i < arguments.count(); ++i)
+@@ -983,15 +984,16 @@
+                 envp = _q_dupEnvironment(environment.d.constData()->vars, 
&envc);
+             }
+ 
+-            QByteArray tmp;
+             if (!program.contains(QLatin1Char('/'))) {
++                // findExecutable() returns its argument if it's an absolute 
path,
++                // otherwise it searches $PATH; returns empty if not found 
(we handle
++                // that case much later)
+                 const QString &exeFilePath = 
QStandardPaths::findExecutable(program);
+-                if (!exeFilePath.isEmpty())
+-                    tmp = QFile::encodeName(exeFilePath);
++                const QByteArray &tmp = QFile::encodeName(exeFilePath);
++                argv[0] = ::strdup(tmp.constData());
++            } else {
++                argv[0] = ::strdup(QFile::encodeName(program));
+             }
+-            if (tmp.isEmpty())
+-                tmp = QFile::encodeName(program);
+-            argv[0] = tmp.data();
+ 
+             if (envp)
+                 qt_safe_execve(argv[0], argv, envp);
+Index: 
qtbase-opensource-src-5.15.2+dfsg/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
+===================================================================
+--- 
qtbase-opensource-src-5.15.2+dfsg.orig/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
 2024-03-05 13:21:06.432881985 +0100
++++ 
qtbase-opensource-src-5.15.2+dfsg/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
      2024-03-05 13:21:57.744931492 +0100
+@@ -1449,7 +1449,7 @@
+ {
+ #if QT_CONFIG(process)
+     QProcess testProcess;
+-    testProcess.start("desktopsettingsaware_helper");
++    testProcess.start("./desktopsettingsaware_helper");
+     QVERIFY2(testProcess.waitForStarted(),
+              qPrintable(QString::fromLatin1("Cannot start 
'desktopsettingsaware_helper': %1").arg(testProcess.errorString())));
+     QVERIFY(testProcess.waitForFinished(10000));
+@@ -2365,7 +2365,7 @@
+ #if QT_CONFIG(process)
+     QProcess testProcess;
+     QStringList arguments;
+-    testProcess.start("modal_helper", arguments);
++    testProcess.start("./modal_helper", arguments);
+     QVERIFY2(testProcess.waitForStarted(),
+              qPrintable(QString::fromLatin1("Cannot start 'modal_helper': 
%1").arg(testProcess.errorString())));
+     QVERIFY(testProcess.waitForFinished(20000));
diff -Nru qtbase-opensource-src-5.15.2+dfsg/debian/patches/CVE-2023-24607.diff 
qtbase-opensource-src-5.15.2+dfsg/debian/patches/CVE-2023-24607.diff
--- qtbase-opensource-src-5.15.2+dfsg/debian/patches/CVE-2023-24607.diff        
1970-01-01 01:00:00.000000000 +0100
+++ qtbase-opensource-src-5.15.2+dfsg/debian/patches/CVE-2023-24607.diff        
2024-03-05 13:24:50.000000000 +0100
@@ -0,0 +1,332 @@
+Description: Fix denial-of-service in Qt SQL ODBC driver plugin
+Origin: upstream, 
https://download.qt.io/official_releases/qt/5.15/CVE-2023-24607-qtbase-5.15.diff
+Last-Update: 2023-02-26
+
+Index: 
qtbase-opensource-src-5.15.2+dfsg/src/plugins/sqldrivers/odbc/qsql_odbc.cpp
+===================================================================
+--- 
qtbase-opensource-src-5.15.2+dfsg.orig/src/plugins/sqldrivers/odbc/qsql_odbc.cpp
   2024-03-05 13:24:44.661090169 +0100
++++ 
qtbase-opensource-src-5.15.2+dfsg/src/plugins/sqldrivers/odbc/qsql_odbc.cpp     
   2024-03-05 13:24:44.657090165 +0100
+@@ -92,23 +92,39 @@
+     return result;
+ }
+ 
++template <size_t SizeOfChar = sizeof(SQLTCHAR)>
++void toSQLTCHARImpl(QVarLengthArray<SQLTCHAR> &result, const QString &input); 
// primary template undefined
++
++template <typename Container>
++void do_append(QVarLengthArray<SQLTCHAR> &result, const Container &c)
++{
++    result.append(reinterpret_cast<const SQLTCHAR *>(c.data()), c.size());
++}
++
++template <>
++void toSQLTCHARImpl<1>(QVarLengthArray<SQLTCHAR> &result, const QString 
&input)
++{
++    const auto u8 = input.toUtf8();
++    do_append(result, u8);
++}
++
++template <>
++void toSQLTCHARImpl<2>(QVarLengthArray<SQLTCHAR> &result, const QString 
&input)
++{
++    do_append(result, input);
++}
++
++template <>
++void toSQLTCHARImpl<4>(QVarLengthArray<SQLTCHAR> &result, const QString 
&input)
++{
++    const auto u32 = input.toUcs4();
++    do_append(result, u32);
++}
++
+ inline static QVarLengthArray<SQLTCHAR> toSQLTCHAR(const QString &input)
+ {
+     QVarLengthArray<SQLTCHAR> result;
+-    result.resize(input.size());
+-    switch(sizeof(SQLTCHAR)) {
+-        case 1:
+-            memcpy(result.data(), input.toUtf8().data(), input.size());
+-            break;
+-        case 2:
+-            memcpy(result.data(), input.unicode(), input.size() * 2);
+-            break;
+-        case 4:
+-            memcpy(result.data(), input.toUcs4().data(), input.size() * 4);
+-            break;
+-        default:
+-            qCritical("sizeof(SQLTCHAR) is %d. Don't know how to handle 
this.", int(sizeof(SQLTCHAR)));
+-    }
++    toSQLTCHARImpl(result, input);
+     result.append(0); // make sure it's null terminated, doesn't matter if it 
already is, it does if it isn't.
+     return result;
+ }
+@@ -763,6 +779,14 @@
+     return quote;
+ }
+ 
++static SQLRETURN qt_string_SQLSetConnectAttr(SQLHDBC handle, SQLINTEGER attr, 
const QString &val)
++{
++    auto encoded = toSQLTCHAR(val);
++    return SQLSetConnectAttr(handle, attr,
++                             encoded.data(),
++                             SQLINTEGER(encoded.size() * sizeof(SQLTCHAR))); 
// size in bytes
++}
++
+ 
+ bool QODBCDriverPrivate::setConnectionOptions(const QString& connOpts)
+ {
+@@ -798,10 +822,7 @@
+             v = val.toUInt();
+             r = SQLSetConnectAttr(hDbc, SQL_ATTR_LOGIN_TIMEOUT, (SQLPOINTER) 
size_t(v), 0);
+         } else if (opt.toUpper() == 
QLatin1String("SQL_ATTR_CURRENT_CATALOG")) {
+-            val.utf16(); // 0 terminate
+-            r = SQLSetConnectAttr(hDbc, SQL_ATTR_CURRENT_CATALOG,
+-                                    toSQLTCHAR(val).data(),
+-                                    val.length()*sizeof(SQLTCHAR));
++            r = qt_string_SQLSetConnectAttr(hDbc, SQL_ATTR_CURRENT_CATALOG, 
val);
+         } else if (opt.toUpper() == QLatin1String("SQL_ATTR_METADATA_ID")) {
+             if (val.toUpper() == QLatin1String("SQL_TRUE")) {
+                 v = SQL_TRUE;
+@@ -816,10 +837,7 @@
+             v = val.toUInt();
+             r = SQLSetConnectAttr(hDbc, SQL_ATTR_PACKET_SIZE, (SQLPOINTER) 
size_t(v), 0);
+         } else if (opt.toUpper() == QLatin1String("SQL_ATTR_TRACEFILE")) {
+-            val.utf16(); // 0 terminate
+-            r = SQLSetConnectAttr(hDbc, SQL_ATTR_TRACEFILE,
+-                                    toSQLTCHAR(val).data(),
+-                                    val.length()*sizeof(SQLTCHAR));
++            r = qt_string_SQLSetConnectAttr(hDbc, SQL_ATTR_TRACEFILE, val);
+         } else if (opt.toUpper() == QLatin1String("SQL_ATTR_TRACE")) {
+             if (val.toUpper() == QLatin1String("SQL_OPT_TRACE_OFF")) {
+                 v = SQL_OPT_TRACE_OFF;
+@@ -1022,9 +1040,12 @@
+         return false;
+     }
+ 
+-    r = SQLExecDirect(d->hStmt,
+-                       toSQLTCHAR(query).data(),
+-                       (SQLINTEGER) query.length());
++    {
++        auto encoded = toSQLTCHAR(query);
++        r = SQLExecDirect(d->hStmt,
++                          encoded.data(),
++                          SQLINTEGER(encoded.size()));
++    }
+     if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO && r!= SQL_NO_DATA) {
+         setLastError(qMakeError(QCoreApplication::translate("QODBCResult",
+                      "Unable to execute statement"), 
QSqlError::StatementError, d));
+@@ -1370,9 +1391,12 @@
+         return false;
+     }
+ 
+-    r = SQLPrepare(d->hStmt,
+-                    toSQLTCHAR(query).data(),
+-                    (SQLINTEGER) query.length());
++    {
++        auto encoded = toSQLTCHAR(query);
++        r = SQLPrepare(d->hStmt,
++                       encoded.data(),
++                       SQLINTEGER(encoded.size()));
++    }
+ 
+     if (r != SQL_SUCCESS) {
+         setLastError(qMakeError(QCoreApplication::translate("QODBCResult",
+@@ -1400,7 +1424,7 @@
+         SQLCloseCursor(d->hStmt);
+ 
+     QVector<QVariant>& values = boundValues();
+-    QVector<QByteArray> tmpStorage(values.count(), QByteArray()); // holds 
temporary buffers
++    QVector<QByteArray> tmpStorage(values.count(), QByteArray()); // targets 
for SQLBindParameter()
+     QVarLengthArray<SQLLEN, 32> indicators(values.count());
+     memset(indicators.data(), 0, indicators.size() * sizeof(SQLLEN));
+ 
+@@ -1579,35 +1603,36 @@
+             case QVariant::String:
+                 if (d->unicode) {
+                     QByteArray &ba = tmpStorage[i];
+-                    QString str = val.toString();
++                    {
++                        const auto encoded = toSQLTCHAR(val.toString());
++                        ba = QByteArray(reinterpret_cast<const char 
*>(encoded.data()),
++                                        encoded.size() * sizeof(SQLTCHAR));
++                    }
++
+                     if (*ind != SQL_NULL_DATA)
+-                        *ind = str.length() * sizeof(SQLTCHAR);
+-                    int strSize = str.length() * sizeof(SQLTCHAR);
++                        *ind = ba.size();
+ 
+                     if (bindValueType(i) & QSql::Out) {
+-                        const QVarLengthArray<SQLTCHAR> a(toSQLTCHAR(str));
+-                        ba = QByteArray((const char *)a.constData(), a.size() 
* sizeof(SQLTCHAR));
+                         r = SQLBindParameter(d->hStmt,
+                                             i + 1,
+                                             qParamType[bindValueType(i) & 
QSql::InOut],
+                                             SQL_C_TCHAR,
+-                                            strSize > 254 ? SQL_WLONGVARCHAR 
: SQL_WVARCHAR,
++                                            ba.size() > 254 ? 
SQL_WLONGVARCHAR : SQL_WVARCHAR,
+                                             0, // god knows... don't change 
this!
+                                             0,
+-                                            ba.data(),
++                                            const_cast<char 
*>(ba.constData()), // don't detach
+                                             ba.size(),
+                                             ind);
+                         break;
+                     }
+-                    ba = QByteArray ((const char 
*)toSQLTCHAR(str).constData(), str.size()*sizeof(SQLTCHAR));
+                     r = SQLBindParameter(d->hStmt,
+                                           i + 1,
+                                           qParamType[bindValueType(i) & 
QSql::InOut],
+                                           SQL_C_TCHAR,
+-                                          strSize > 254 ? SQL_WLONGVARCHAR : 
SQL_WVARCHAR,
+-                                          strSize,
++                                          ba.size() > 254 ? SQL_WLONGVARCHAR 
: SQL_WVARCHAR,
++                                          ba.size(),
+                                           0,
+-                                          const_cast<char *>(ba.constData()),
++                                          const_cast<char *>(ba.constData()), 
// don't detach
+                                           ba.size(),
+                                           ind);
+                     break;
+@@ -1715,10 +1740,11 @@
+             case QVariant::String:
+                 if (d->unicode) {
+                     if (bindValueType(i) & QSql::Out) {
+-                        const QByteArray &first = tmpStorage.at(i);
+-                        QVarLengthArray<SQLTCHAR> array;
+-                        array.append((const SQLTCHAR *)first.constData(), 
first.size());
+-                        values[i] = fromSQLTCHAR(array, 
first.size()/sizeof(SQLTCHAR));
++                        const QByteArray &bytes = tmpStorage.at(i);
++                        const auto strSize = bytes.size() / 
int(sizeof(SQLTCHAR));
++                        QVarLengthArray<SQLTCHAR> string(strSize);
++                        memcpy(string.data(), bytes.data(), strSize * 
sizeof(SQLTCHAR));
++                        values[i] = fromSQLTCHAR(string);
+                     }
+                     break;
+                 }
+@@ -1965,14 +1991,16 @@
+     SQLSMALLINT cb;
+     QVarLengthArray<SQLTCHAR> connOut(1024);
+     memset(connOut.data(), 0, connOut.size() * sizeof(SQLTCHAR));
+-    r = SQLDriverConnect(d->hDbc,
+-                          NULL,
+-                          toSQLTCHAR(connQStr).data(),
+-                          (SQLSMALLINT)connQStr.length(),
+-                          connOut.data(),
+-                          1024,
+-                          &cb,
+-                          /*SQL_DRIVER_NOPROMPT*/0);
++    {
++        auto encoded = toSQLTCHAR(connQStr);
++        r = SQLDriverConnect(d->hDbc,
++                             nullptr,
++                             encoded.data(), SQLSMALLINT(encoded.size()),
++                             connOut.data(),
++                             1024,
++                             &cb,
++                             /*SQL_DRIVER_NOPROMPT*/0);
++    }
+ 
+     if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO) {
+         setLastError(qMakeError(tr("Unable to connect"), 
QSqlError::ConnectionError, d));
+@@ -2351,17 +2379,15 @@
+     if (tableType.isEmpty())
+         return tl;
+ 
+-    QString joinedTableTypeString = tableType.join(QLatin1Char(','));
++    {
++        auto joinedTableTypeString = toSQLTCHAR(tableType.join(u','));
+ 
+-    r = SQLTables(hStmt,
+-                   NULL,
+-                   0,
+-                   NULL,
+-                   0,
+-                   NULL,
+-                   0,
+-                   toSQLTCHAR(joinedTableTypeString).data(),
+-                   joinedTableTypeString.length() /* characters, not bytes 
*/);
++        r = SQLTables(hStmt,
++                      nullptr, 0,
++                      nullptr, 0,
++                      nullptr, 0,
++                      joinedTableTypeString.data(), 
joinedTableTypeString.size());
++    }
+ 
+     if (r != SQL_SUCCESS)
+         qSqlWarning(QLatin1String("QODBCDriver::tables Unable to execute 
table list"), d);
+@@ -2435,28 +2461,30 @@
+                         SQL_ATTR_CURSOR_TYPE,
+                         (SQLPOINTER)SQL_CURSOR_FORWARD_ONLY,
+                         SQL_IS_UINTEGER);
+-    r = SQLPrimaryKeys(hStmt,
+-                        catalog.length() == 0 ? NULL : 
toSQLTCHAR(catalog).data(),
+-                        catalog.length(),
+-                        schema.length() == 0 ? NULL : 
toSQLTCHAR(schema).data(),
+-                        schema.length(),
+-                        toSQLTCHAR(table).data(),
+-                        table.length() /* in characters, not in bytes */);
++    {
++        auto c = toSQLTCHAR(catalog);
++        auto s = toSQLTCHAR(schema);
++        auto t = toSQLTCHAR(table);
++        r = SQLPrimaryKeys(hStmt,
++                           catalog.isEmpty() ? nullptr : c.data(), c.size(),
++                           schema.isEmpty()  ? nullptr : s.data(), s.size(),
++                           t.data(), t.size());
++    }
+ 
+     // if the SQLPrimaryKeys() call does not succeed (e.g the driver
+     // does not support it) - try an alternative method to get hold of
+     // the primary index (e.g MS Access and FoxPro)
+     if (r != SQL_SUCCESS) {
+-            r = SQLSpecialColumns(hStmt,
+-                        SQL_BEST_ROWID,
+-                        catalog.length() == 0 ? NULL : 
toSQLTCHAR(catalog).data(),
+-                        catalog.length(),
+-                        schema.length() == 0 ? NULL : 
toSQLTCHAR(schema).data(),
+-                        schema.length(),
+-                        toSQLTCHAR(table).data(),
+-                        table.length(),
+-                        SQL_SCOPE_CURROW,
+-                        SQL_NULLABLE);
++        auto c = toSQLTCHAR(catalog);
++        auto s = toSQLTCHAR(schema);
++        auto t = toSQLTCHAR(table);
++        r = SQLSpecialColumns(hStmt,
++                              SQL_BEST_ROWID,
++                              catalog.isEmpty() ? nullptr : c.data(), 
c.size(),
++                              schema.isEmpty()  ? nullptr : s.data(), 
s.size(),
++                              t.data(), t.size(),
++                              SQL_SCOPE_CURROW,
++                              SQL_NULLABLE);
+ 
+             if (r != SQL_SUCCESS) {
+                 qSqlWarning(QLatin1String("QODBCDriver::primaryIndex: Unable 
to execute primary key list"), d);
+@@ -2537,15 +2565,17 @@
+                         SQL_ATTR_CURSOR_TYPE,
+                         (SQLPOINTER)SQL_CURSOR_FORWARD_ONLY,
+                         SQL_IS_UINTEGER);
+-    r =  SQLColumns(hStmt,
+-                     catalog.length() == 0 ? NULL : 
toSQLTCHAR(catalog).data(),
+-                     catalog.length(),
+-                     schema.length() == 0 ? NULL : toSQLTCHAR(schema).data(),
+-                     schema.length(),
+-                     toSQLTCHAR(table).data(),
+-                     table.length(),
+-                     NULL,
+-                     0);
++    {
++        auto c = toSQLTCHAR(catalog);
++        auto s = toSQLTCHAR(schema);
++        auto t = toSQLTCHAR(table);
++        r =  SQLColumns(hStmt,
++                        catalog.isEmpty() ? nullptr : c.data(), c.size(),
++                        schema.isEmpty()  ? nullptr : s.data(), s.size(),
++                        t.data(), t.size(),
++                        nullptr,
++                        0);
++    }
+     if (r != SQL_SUCCESS)
+         qSqlWarning(QLatin1String("QODBCDriver::record: Unable to execute 
column list"), d);
+ 
diff -Nru qtbase-opensource-src-5.15.2+dfsg/debian/patches/CVE-2023-32762.diff 
qtbase-opensource-src-5.15.2+dfsg/debian/patches/CVE-2023-32762.diff
--- qtbase-opensource-src-5.15.2+dfsg/debian/patches/CVE-2023-32762.diff        
1970-01-01 01:00:00.000000000 +0100
+++ qtbase-opensource-src-5.15.2+dfsg/debian/patches/CVE-2023-32762.diff        
2024-03-05 13:48:39.000000000 +0100
@@ -0,0 +1,47 @@
+commit 1b736a815be0222f4b24289cf17575fc15707305
+Author: Mårten Nordheim <marten.nordh...@qt.io>
+Date:   Fri May 5 11:07:26 2023 +0200
+
+    Hsts: match header names case insensitively
+    
+    Header field names are always considered to be case-insensitive.
+    
+    Pick-to: 6.5 6.5.1 6.2 5.15
+    Fixes: QTBUG-113392
+    Change-Id: Ifb4def4bb7f2ac070416cdc76581a769f1e52b43
+    Reviewed-by: Qt CI Bot <qt_ci_...@qt-project.org>
+    Reviewed-by: Edward Welbourne <edward.welbou...@qt.io>
+    Reviewed-by: Volker Hilsheimer <volker.hilshei...@qt.io>
+
+Index: qtbase-opensource-src-5.15.2+dfsg/src/network/access/qhsts.cpp
+===================================================================
+--- qtbase-opensource-src-5.15.2+dfsg.orig/src/network/access/qhsts.cpp        
2024-03-05 13:48:37.054356050 +0100
++++ qtbase-opensource-src-5.15.2+dfsg/src/network/access/qhsts.cpp     
2024-03-05 13:48:37.054356050 +0100
+@@ -364,8 +364,8 @@
+ bool QHstsHeaderParser::parse(const QList<QPair<QByteArray, QByteArray>> 
&headers)
+ {
+     for (const auto &h : headers) {
+-        // We use '==' since header name was already 'trimmed' for us:
+-        if (h.first == "Strict-Transport-Security") {
++        // We compare directly because header name was already 'trimmed' for 
us:
++        if (h.first.compare("Strict-Transport-Security", Qt::CaseInsensitive) 
== 0) {
+             header = h.second;
+             // RFC6797, 8.1:
+             //
+Index: 
qtbase-opensource-src-5.15.2+dfsg/tests/auto/network/access/hsts/tst_qhsts.cpp
+===================================================================
+--- 
qtbase-opensource-src-5.15.2+dfsg.orig/tests/auto/network/access/hsts/tst_qhsts.cpp
        2024-03-05 13:48:37.054356050 +0100
++++ 
qtbase-opensource-src-5.15.2+dfsg/tests/auto/network/access/hsts/tst_qhsts.cpp  
   2024-03-05 13:48:37.054356050 +0100
+@@ -242,6 +242,12 @@
+     QVERIFY(parser.includeSubDomains());
+ 
+     list.pop_back();
++    list << Header("strict-transport-security", 
"includeSubDomains;max-age=1000");
++    QVERIFY(parser.parse(list));
++    QVERIFY(parser.expirationDate() > QDateTime::currentDateTimeUtc());
++    QVERIFY(parser.includeSubDomains());
++
++    list.pop_back();
+     // Invalid (includeSubDomains twice):
+     list << Header("Strict-Transport-Security", "max-age = 1000 ; 
includeSubDomains;includeSubDomains");
+     QVERIFY(!parser.parse(list));
diff -Nru qtbase-opensource-src-5.15.2+dfsg/debian/patches/CVE-2023-32763.diff 
qtbase-opensource-src-5.15.2+dfsg/debian/patches/CVE-2023-32763.diff
--- qtbase-opensource-src-5.15.2+dfsg/debian/patches/CVE-2023-32763.diff        
1970-01-01 01:00:00.000000000 +0100
+++ qtbase-opensource-src-5.15.2+dfsg/debian/patches/CVE-2023-32763.diff        
2024-03-05 12:57:24.000000000 +0100
@@ -0,0 +1,54 @@
+Description: fix buffer overflow in Qt SVG
+ Adds qAddOverflow and qMulOverflow definitions to QFixed.
+Origin: upstream, 
https://download.qt.io/official_releases/qt/5.15/CVE-2023-32763-qtbase-5.15.diff
+Last-Update: 2023-05-22
+
+Index: qtbase-opensource-src-5.15.2+dfsg/src/gui/painting/qfixed_p.h
+===================================================================
+--- qtbase-opensource-src-5.15.2+dfsg.orig/src/gui/painting/qfixed_p.h 
2024-03-05 12:57:22.447571651 +0100
++++ qtbase-opensource-src-5.15.2+dfsg/src/gui/painting/qfixed_p.h      
2024-03-05 12:57:22.443571651 +0100
+@@ -54,6 +54,7 @@
+ #include <QtGui/private/qtguiglobal_p.h>
+ #include "QtCore/qdebug.h"
+ #include "QtCore/qpoint.h"
++#include <QtCore/private/qnumeric_p.h>
+ #include "QtCore/qsize.h"
+ 
+ QT_BEGIN_NAMESPACE
+@@ -182,6 +183,14 @@
+ Q_DECL_CONSTEXPR inline bool operator>(const QFixed &f, int i) { return 
f.value() > i * 64; }
+ Q_DECL_CONSTEXPR inline bool operator>(int i, const QFixed &f) { return i * 
64 > f.value(); }
+ 
++inline bool qAddOverflow(QFixed v1, QFixed v2, QFixed *r)
++{
++    int val;
++    bool result = add_overflow(v1.value(), v2.value(), &val);
++    r->setValue(val);
++    return result;
++}
++
+ #ifndef QT_NO_DEBUG_STREAM
+ inline QDebug &operator<<(QDebug &dbg, const QFixed &f)
+ { return dbg << f.toReal(); }
+Index: qtbase-opensource-src-5.15.2+dfsg/src/gui/text/qtextlayout.cpp
+===================================================================
+--- qtbase-opensource-src-5.15.2+dfsg.orig/src/gui/text/qtextlayout.cpp        
2024-03-05 12:57:22.447571651 +0100
++++ qtbase-opensource-src-5.15.2+dfsg/src/gui/text/qtextlayout.cpp     
2024-03-05 12:57:22.443571651 +0100
+@@ -2138,11 +2138,14 @@
+         eng->maxWidth = qMax(eng->maxWidth, line.textWidth);
+     } else {
+         eng->minWidth = qMax(eng->minWidth, lbh.minw);
+-        eng->maxWidth += line.textWidth;
++        if (qAddOverflow(eng->maxWidth, line.textWidth, &eng->maxWidth))
++            eng->maxWidth = QFIXED_MAX;
+     }
+ 
+-    if (line.textWidth > 0 && item < eng->layoutData->items.size())
+-        eng->maxWidth += lbh.spaceData.textWidth;
++    if (line.textWidth > 0 && item < eng->layoutData->items.size()) {
++        if (qAddOverflow(eng->maxWidth, lbh.spaceData.textWidth, 
&eng->maxWidth))
++            eng->maxWidth = QFIXED_MAX;
++    }
+ 
+     line.textWidth += trailingSpace;
+     if (lbh.spaceData.length) {
diff -Nru qtbase-opensource-src-5.15.2+dfsg/debian/patches/CVE-2023-33285.diff 
qtbase-opensource-src-5.15.2+dfsg/debian/patches/CVE-2023-33285.diff
--- qtbase-opensource-src-5.15.2+dfsg/debian/patches/CVE-2023-33285.diff        
1970-01-01 01:00:00.000000000 +0100
+++ qtbase-opensource-src-5.15.2+dfsg/debian/patches/CVE-2023-33285.diff        
2023-05-25 12:45:05.000000000 +0200
@@ -0,0 +1,77 @@
+Description: QDnsLookup/Unix: make sure we don't overflow the buffer
+ The DNS Records are variable length and encode their size in 16 bits
+ before the Record Data (RDATA). Ensure that both the RDATA and the
+ Record header fields before it fall inside the buffer we have.
+ .
+ Additionally reject any replies containing more than one query records.
+Origin: upstream, 
https://code.qt.io/cgit/qt/qtbase.git/commit/?id=7dba2c87619d558a
+Last-Update: 2023-05-25
+
+--- a/src/network/kernel/qdnslookup_unix.cpp
++++ b/src/network/kernel/qdnslookup_unix.cpp
+@@ -227,7 +227,6 @@ void QDnsLookupRunnable::query(const int
+     // responseLength in case of error, we still can extract the
+     // exact error code from the response.
+     HEADER *header = (HEADER*)response;
+-    const int answerCount = ntohs(header->ancount);
+     switch (header->rcode) {
+     case NOERROR:
+         break;
+@@ -260,18 +259,31 @@ void QDnsLookupRunnable::query(const int
+         return;
+     }
+ 
+-    // Skip the query host, type (2 bytes) and class (2 bytes).
+     char host[PACKETSZ], answer[PACKETSZ];
+     unsigned char *p = response + sizeof(HEADER);
+-    int status = local_dn_expand(response, response + responseLength, p, 
host, sizeof(host));
+-    if (status < 0) {
++    int status;
++
++    if (ntohs(header->qdcount) == 1) {
++        // Skip the query host, type (2 bytes) and class (2 bytes).
++        status = local_dn_expand(response, response + responseLength, p, 
host, sizeof(host));
++        if (status < 0) {
++            reply->error = QDnsLookup::InvalidReplyError;
++            reply->errorString = tr("Could not expand domain name");
++            return;
++        }
++        if ((p - response) + status + 4 >= responseLength)
++            header->qdcount = 0xffff;   // invalid reply below
++        else
++            p += status + 4;
++    }
++    if (ntohs(header->qdcount) > 1) {
+         reply->error = QDnsLookup::InvalidReplyError;
+-        reply->errorString = tr("Could not expand domain name");
++        reply->errorString = tr("Invalid reply received");
+         return;
+     }
+-    p += status + 4;
+ 
+     // Extract results.
++    const int answerCount = ntohs(header->ancount);
+     int answerIndex = 0;
+     while ((p < response + responseLength) && (answerIndex < answerCount)) {
+         status = local_dn_expand(response, response + responseLength, p, 
host, sizeof(host));
+@@ -283,6 +295,11 @@ void QDnsLookupRunnable::query(const int
+         const QString name = QUrl::fromAce(host);
+ 
+         p += status;
++
++        if ((p - response) + 10 > responseLength) {
++            // probably just a truncated reply, return what we have
++            return;
++        }
+         const quint16 type = (p[0] << 8) | p[1];
+         p += 2; // RR type
+         p += 2; // RR class
+@@ -290,6 +307,8 @@ void QDnsLookupRunnable::query(const int
+         p += 4;
+         const quint16 size = (p[0] << 8) | p[1];
+         p += 2;
++        if ((p - response) + size > responseLength)
++            return;             // truncated
+ 
+         if (type == QDnsLookup::A) {
+             if (size != 4) {
diff -Nru qtbase-opensource-src-5.15.2+dfsg/debian/patches/CVE-2023-34410.diff 
qtbase-opensource-src-5.15.2+dfsg/debian/patches/CVE-2023-34410.diff
--- qtbase-opensource-src-5.15.2+dfsg/debian/patches/CVE-2023-34410.diff        
1970-01-01 01:00:00.000000000 +0100
+++ qtbase-opensource-src-5.15.2+dfsg/debian/patches/CVE-2023-34410.diff        
2024-04-28 22:48:02.000000000 +0200
@@ -0,0 +1,56 @@
+Index: 
qtbase-opensource-src-5.15.2+dfsg/src/network/ssl/qsslsocket_schannel.cpp
+===================================================================
+--- 
qtbase-opensource-src-5.15.2+dfsg.orig/src/network/ssl/qsslsocket_schannel.cpp  
   2024-04-25 14:19:26.756392964 +0200
++++ qtbase-opensource-src-5.15.2+dfsg/src/network/ssl/qsslsocket_schannel.cpp  
2024-04-25 14:19:26.752392971 +0200
+@@ -1877,6 +1877,28 @@
+     if (configuration.peerVerifyDepth > 0 && 
DWORD(configuration.peerVerifyDepth) < verifyDepth)
+         verifyDepth = DWORD(configuration.peerVerifyDepth);
+ 
++    const auto &caCertificates = q->sslConfiguration().caCertificates();
++
++    if (!rootCertOnDemandLoadingAllowed()
++            && !(chain->TrustStatus.dwErrorStatus & 
CERT_TRUST_IS_PARTIAL_CHAIN)
++            && (q->peerVerifyMode() == QSslSocket::VerifyPeer
++                    || (isClient && q->peerVerifyMode() == 
QSslSocket::AutoVerifyPeer))) {
++        // When verifying a peer Windows "helpfully" builds a chain that
++        // may include roots from the system store. But we don't want that if
++        // the user has set their own CA certificates.
++        // Since Windows claims this is not a partial chain the root is 
included
++        // and we have to check that it is one of our configured CAs.
++        CERT_CHAIN_ELEMENT *element = chain->rgpElement[chain->cElement - 1];
++        QSslCertificate certificate = getCertificateFromChainElement(element);
++        if (!caCertificates.contains(certificate)) {
++            auto error = QSslError(QSslError::CertificateUntrusted, 
certificate);
++            sslErrors += error;
++            emit q->peerVerifyError(error);
++            if (q->state() != QAbstractSocket::ConnectedState)
++                return false;
++        }
++    }
++
+     for (DWORD i = 0; i < verifyDepth; i++) {
+         CERT_CHAIN_ELEMENT *element = chain->rgpElement[i];
+         QSslCertificate certificate = getCertificateFromChainElement(element);
+Index: qtbase-opensource-src-5.15.2+dfsg/src/network/ssl/qsslsocket.cpp
+===================================================================
+--- qtbase-opensource-src-5.15.2+dfsg.orig/src/network/ssl/qsslsocket.cpp      
2024-04-25 14:19:26.756392964 +0200
++++ qtbase-opensource-src-5.15.2+dfsg/src/network/ssl/qsslsocket.cpp   
2024-04-25 14:19:26.752392971 +0200
+@@ -2221,6 +2221,10 @@
+     , flushTriggered(false)
+ {
+     QSslConfigurationPrivate::deepCopyDefaultConfiguration(&configuration);
++    // If the global configuration doesn't allow root certificates to be 
loaded
++    // on demand then we have to disable it for this socket as well.
++    if (!configuration.allowRootCertOnDemandLoading)
++        allowRootCertOnDemandLoading = false;
+ }
+ 
+ /*!
+@@ -2470,6 +2474,7 @@
+     ptr->sessionProtocol = global->sessionProtocol;
+     ptr->ciphers = global->ciphers;
+     ptr->caCertificates = global->caCertificates;
++    ptr->allowRootCertOnDemandLoading = global->allowRootCertOnDemandLoading;
+     ptr->protocol = global->protocol;
+     ptr->peerVerifyMode = global->peerVerifyMode;
+     ptr->peerVerifyDepth = global->peerVerifyDepth;
diff -Nru qtbase-opensource-src-5.15.2+dfsg/debian/patches/CVE-2023-37369.diff 
qtbase-opensource-src-5.15.2+dfsg/debian/patches/CVE-2023-37369.diff
--- qtbase-opensource-src-5.15.2+dfsg/debian/patches/CVE-2023-37369.diff        
1970-01-01 01:00:00.000000000 +0100
+++ qtbase-opensource-src-5.15.2+dfsg/debian/patches/CVE-2023-37369.diff        
2024-04-28 22:48:02.000000000 +0200
@@ -0,0 +1,202 @@
+Index: 
qtbase-opensource-src-5.15.2+dfsg/src/corelib/serialization/qxmlstream.cpp
+===================================================================
+--- 
qtbase-opensource-src-5.15.2+dfsg.orig/src/corelib/serialization/qxmlstream.cpp 
   2024-04-26 13:23:27.490939469 +0200
++++ qtbase-opensource-src-5.15.2+dfsg/src/corelib/serialization/qxmlstream.cpp 
2024-04-26 13:24:24.074800856 +0200
+@@ -1302,11 +1302,19 @@
+     return n;
+ }
+ 
+-inline int QXmlStreamReaderPrivate::fastScanName(int *prefix)
++// Fast scan an XML attribute name (e.g. "xml:lang").
++inline QXmlStreamReaderPrivate::FastScanNameResult
++QXmlStreamReaderPrivate::fastScanName(Value *val)
+ {
+     int n = 0;
+     uint c;
+     while ((c = getChar()) != StreamEOF) {
++        if (n >= 4096) {
++            // This is too long to be a sensible name, and
++            // can exhaust memory, or the range of decltype(*prefix)
++            raiseNamePrefixTooLongError();
++            return {};
++        }
+         switch (c) {
+         case '\n':
+         case ' ':
+@@ -1334,23 +1342,23 @@
+         case '+':
+         case '*':
+             putChar(c);
+-            if (prefix && *prefix == n+1) {
+-                *prefix = 0;
++            if (val && val->prefix == n + 1) {
++                val->prefix = 0;
+                 putChar(':');
+                 --n;
+             }
+-            return n;
++            return FastScanNameResult(n);
+         case ':':
+-            if (prefix) {
+-                if (*prefix == 0) {
+-                    *prefix = n+2;
++            if (val) {
++                if (val->prefix == 0) {
++                    val->prefix = n + 2;
+                 } else { // only one colon allowed according to the namespace 
spec.
+                     putChar(c);
+-                    return n;
++                    return FastScanNameResult(n);
+                 }
+             } else {
+                 putChar(c);
+-                return n;
++                return FastScanNameResult(n);
+             }
+             Q_FALLTHROUGH();
+         default:
+@@ -1359,12 +1367,12 @@
+         }
+     }
+ 
+-    if (prefix)
+-        *prefix = 0;
++    if (val)
++        val->prefix = 0;
+     int pos = textBuffer.size() - n;
+     putString(textBuffer, pos);
+     textBuffer.resize(pos);
+-    return 0;
++    return FastScanNameResult(0);
+ }
+ 
+ enum NameChar { NameBeginning, NameNotBeginning, NotName };
+@@ -1873,6 +1881,14 @@
+     raiseError(QXmlStreamReader::NotWellFormedError, message);
+ }
+ 
++void QXmlStreamReaderPrivate::raiseNamePrefixTooLongError()
++{
++    // TODO: add a ImplementationLimitsExceededError and use it instead
++    raiseError(QXmlStreamReader::NotWellFormedError,
++               QXmlStream::tr("Length of XML attribute name exceeds 
implemnetation limits (4KiB "
++                              "characters)."));
++}
++
+ void QXmlStreamReaderPrivate::parseError()
+ {
+ 
+Index: qtbase-opensource-src-5.15.2+dfsg/src/corelib/serialization/qxmlstream.g
+===================================================================
+--- 
qtbase-opensource-src-5.15.2+dfsg.orig/src/corelib/serialization/qxmlstream.g   
   2024-04-26 13:23:27.490939469 +0200
++++ qtbase-opensource-src-5.15.2+dfsg/src/corelib/serialization/qxmlstream.g   
2024-04-26 13:23:27.486939479 +0200
+@@ -516,7 +516,16 @@
+     int fastScanLiteralContent();
+     int fastScanSpace();
+     int fastScanContentCharList();
+-    int fastScanName(int *prefix = nullptr);
++
++    struct FastScanNameResult {
++        FastScanNameResult() : ok(false) {}
++        explicit FastScanNameResult(int len) : addToLen(len), ok(true) { }
++        operator bool() { return ok; }
++        int operator*() { Q_ASSERT(ok); return addToLen; }
++        int addToLen;
++        bool ok;
++    };
++    FastScanNameResult fastScanName(Value *val = nullptr);
+     inline int fastScanNMTOKEN();
+ 
+ 
+@@ -525,6 +534,7 @@
+ 
+     void raiseError(QXmlStreamReader::Error error, const QString& message = 
QString());
+     void raiseWellFormedError(const QString &message);
++    void raiseNamePrefixTooLongError();
+ 
+     QXmlStreamEntityResolver *entityResolver;
+ 
+@@ -1809,7 +1819,12 @@
+ qname ::= LETTER;
+ /.
+         case $rule_number: {
+-            sym(1).len += fastScanName(&sym(1).prefix);
++            Value &val = sym(1);
++            if (auto res = fastScanName(&val))
++                val.len += *res;
++            else
++                return false;
++
+             if (atEnd) {
+                 resume($rule_number);
+                 return false;
+@@ -1820,7 +1835,11 @@
+ name ::= LETTER;
+ /.
+         case $rule_number:
+-            sym(1).len += fastScanName();
++            if (auto res = fastScanName())
++                sym(1).len += *res;
++            else
++                return false;
++
+             if (atEnd) {
+                 resume($rule_number);
+                 return false;
+Index: 
qtbase-opensource-src-5.15.2+dfsg/src/corelib/serialization/qxmlstream_p.h
+===================================================================
+--- 
qtbase-opensource-src-5.15.2+dfsg.orig/src/corelib/serialization/qxmlstream_p.h 
   2024-04-26 13:23:27.490939469 +0200
++++ qtbase-opensource-src-5.15.2+dfsg/src/corelib/serialization/qxmlstream_p.h 
2024-04-26 13:23:27.486939479 +0200
+@@ -1005,7 +1005,16 @@
+     int fastScanLiteralContent();
+     int fastScanSpace();
+     int fastScanContentCharList();
+-    int fastScanName(int *prefix = nullptr);
++
++    struct FastScanNameResult {
++        FastScanNameResult() : ok(false) {}
++        explicit FastScanNameResult(int len) : addToLen(len), ok(true) { }
++        operator bool() { return ok; }
++        int operator*() { Q_ASSERT(ok); return addToLen; }
++        int addToLen;
++        bool ok;
++    };
++    FastScanNameResult fastScanName(Value *val = nullptr);
+     inline int fastScanNMTOKEN();
+ 
+ 
+@@ -1014,6 +1023,7 @@
+ 
+     void raiseError(QXmlStreamReader::Error error, const QString& message = 
QString());
+     void raiseWellFormedError(const QString &message);
++    void raiseNamePrefixTooLongError();
+ 
+     QXmlStreamEntityResolver *entityResolver;
+ 
+@@ -1937,7 +1947,12 @@
+         break;
+ 
+         case 262: {
+-            sym(1).len += fastScanName(&sym(1).prefix);
++            Value &val = sym(1);
++            if (auto res = fastScanName(&val))
++                val.len += *res;
++            else
++                return false;
++
+             if (atEnd) {
+                 resume(262);
+                 return false;
+@@ -1945,7 +1960,11 @@
+         } break;
+ 
+         case 263:
+-            sym(1).len += fastScanName();
++            if (auto res = fastScanName())
++                sym(1).len += *res;
++            else
++                return false;
++
+             if (atEnd) {
+                 resume(263);
+                 return false;
diff -Nru qtbase-opensource-src-5.15.2+dfsg/debian/patches/CVE-2023-38197.diff 
qtbase-opensource-src-5.15.2+dfsg/debian/patches/CVE-2023-38197.diff
--- qtbase-opensource-src-5.15.2+dfsg/debian/patches/CVE-2023-38197.diff        
1970-01-01 01:00:00.000000000 +0100
+++ qtbase-opensource-src-5.15.2+dfsg/debian/patches/CVE-2023-38197.diff        
2024-04-28 22:48:02.000000000 +0200
@@ -0,0 +1,219 @@
+Index: 
qtbase-opensource-src-5.15.2+dfsg/src/corelib/serialization/qxmlstream.cpp
+===================================================================
+--- 
qtbase-opensource-src-5.15.2+dfsg.orig/src/corelib/serialization/qxmlstream.cpp 
   2024-04-25 08:25:46.389994553 +0200
++++ qtbase-opensource-src-5.15.2+dfsg/src/corelib/serialization/qxmlstream.cpp 
2024-04-25 08:25:46.385994556 +0200
+@@ -160,7 +160,7 @@
+     addData() or by waiting for it to arrive on the device().
+ 
+     \value UnexpectedElementError The parser encountered an element
+-    that was different to those it expected.
++    or token that was different to those it expected.
+ 
+ */
+ 
+@@ -295,13 +295,34 @@
+ 
+   QXmlStreamReader is a well-formed XML 1.0 parser that does \e not
+   include external parsed entities. As long as no error occurs, the
+-  application code can thus be assured that the data provided by the
+-  stream reader satisfies the W3C's criteria for well-formed XML. For
+-  example, you can be certain that all tags are indeed nested and
+-  closed properly, that references to internal entities have been
+-  replaced with the correct replacement text, and that attributes have
+-  been normalized or added according to the internal subset of the
+-  DTD.
++  application code can thus be assured, that
++  \list
++  \li the data provided by the stream reader satisfies the W3C's
++      criteria for well-formed XML,
++  \li tokens are provided in a valid order.
++  \endlist
++
++  Unless QXmlStreamReader raises an error, it guarantees the following:
++  \list
++  \li All tags are nested and closed properly.
++  \li References to internal entities have been replaced with the
++      correct replacement text.
++  \li Attributes have been normalized or added according to the
++      internal subset of the \l DTD.
++  \li Tokens of type \l StartDocument happen before all others,
++      aside from comments and processing instructions.
++  \li At most one DOCTYPE element (a token of type \l DTD) is present.
++  \li If present, the DOCTYPE appears before all other elements,
++      aside from StartDocument, comments and processing instructions.
++  \endlist
++
++  In particular, once any token of type \l StartElement, \l EndElement,
++  \l Characters, \l EntityReference or \l EndDocument is seen, no
++  tokens of type StartDocument or DTD will be seen. If one is present in
++  the input stream, out of order, an error is raised.
++
++  \note The token types \l Comment and \l ProcessingInstruction may appear
++  anywhere in the stream.
+ 
+   If an error occurs while parsing, atEnd() and hasError() return
+   true, and error() returns the error that occurred. The functions
+@@ -620,6 +641,7 @@
+         d->token = -1;
+         return readNext();
+     }
++    d->checkToken();
+     return d->type;
+ }
+ 
+@@ -740,6 +762,14 @@
+ };
+ 
+ 
++static const char QXmlStreamReader_XmlContextString[] =
++    "Prolog\0"
++    "Body\0";
++
++static const short QXmlStreamReader_XmlContextString_indices[] = {
++    0, 7
++};
++
+ /*!
+     \property  QXmlStreamReader::namespaceProcessing
+     The namespace-processing flag of the stream reader
+@@ -775,6 +805,16 @@
+                          QXmlStreamReader_tokenTypeString_indices[d->type]);
+ }
+ 
++/*!
++   \internal
++   \return \param ctxt (Prolog/Body) as a string.
++ */
++QString contextString(QXmlStreamReaderPrivate::XmlContext ctxt)
++{
++    return QLatin1String(QXmlStreamReader_XmlContextString +
++                         
QXmlStreamReader_XmlContextString_indices[static_cast<int>(ctxt)]);
++}
++
+ #endif // QT_NO_XMLSTREAMREADER
+ 
+ QXmlStreamPrivateTagStack::QXmlStreamPrivateTagStack()
+@@ -866,6 +906,8 @@
+ 
+     type = QXmlStreamReader::NoToken;
+     error = QXmlStreamReader::NoError;
++    currentContext = XmlContext::Prolog;
++    foundDTD = false;
+ }
+ 
+ /*
+@@ -4059,6 +4101,92 @@
+     }
+ }
+ 
++static bool isTokenAllowedInContext(QXmlStreamReader::TokenType type,
++                                               
QXmlStreamReaderPrivate::XmlContext loc)
++{
++    switch (type) {
++    case QXmlStreamReader::StartDocument:
++    case QXmlStreamReader::DTD:
++        return loc == QXmlStreamReaderPrivate::XmlContext::Prolog;
++
++    case QXmlStreamReader::StartElement:
++    case QXmlStreamReader::EndElement:
++    case QXmlStreamReader::Characters:
++    case QXmlStreamReader::EntityReference:
++    case QXmlStreamReader::EndDocument:
++        return loc == QXmlStreamReaderPrivate::XmlContext::Body;
++
++    case QXmlStreamReader::Comment:
++    case QXmlStreamReader::ProcessingInstruction:
++        return true;
++
++    case QXmlStreamReader::NoToken:
++    case QXmlStreamReader::Invalid:
++        return false;
++    default:
++        return false;
++    }
++}
++
++/*!
++   \internal
++   \brief QXmlStreamReader::isValidToken
++   \return \c true if \param type is a valid token type.
++   \return \c false if \param type is an unexpected token,
++   which indicates a non-well-formed or invalid XML stream.
++ */
++bool QXmlStreamReaderPrivate::isValidToken(QXmlStreamReader::TokenType type)
++{
++    // Don't change currentContext, if Invalid or NoToken occur in the prolog
++    if (type == QXmlStreamReader::Invalid || type == 
QXmlStreamReader::NoToken)
++        return false;
++
++    // If a token type gets rejected in the body, there is no recovery
++    const bool result = isTokenAllowedInContext(type, currentContext);
++    if (result || currentContext == XmlContext::Body)
++        return result;
++
++    // First non-Prolog token observed => switch context to body and check 
again.
++    currentContext = XmlContext::Body;
++    return isTokenAllowedInContext(type, currentContext);
++}
++
++/*!
++   \internal
++   Checks token type and raises an error, if it is invalid
++   in the current context (prolog/body).
++ */
++void QXmlStreamReaderPrivate::checkToken()
++{
++    Q_Q(QXmlStreamReader);
++
++    // The token type must be consumed, to keep track if the body has been 
reached.
++    const XmlContext context = currentContext;
++    const bool ok = isValidToken(type);
++
++    // Do nothing if an error has been raised already (going along with an 
unexpected token)
++    if (error != QXmlStreamReader::Error::NoError)
++        return;
++
++    if (!ok) {
++        raiseError(QXmlStreamReader::UnexpectedElementError,
++                   QLatin1String("Unexpected token type %1 in %2.")
++                   .arg(q->tokenString(), contextString(context)));
++        return;
++    }
++
++    if (type != QXmlStreamReader::DTD)
++        return;
++
++    // Raise error on multiple DTD tokens
++    if (foundDTD) {
++        raiseError(QXmlStreamReader::UnexpectedElementError,
++                   QLatin1String("Found second DTD token in 
%1.").arg(contextString(context)));
++    } else {
++        foundDTD = true;
++    }
++}
++
+ /*!
+  \fn bool QXmlStreamAttributes::hasAttribute(const QString &qualifiedName) 
const
+  \since 4.5
+Index: 
qtbase-opensource-src-5.15.2+dfsg/src/corelib/serialization/qxmlstream_p.h
+===================================================================
+--- 
qtbase-opensource-src-5.15.2+dfsg.orig/src/corelib/serialization/qxmlstream_p.h 
   2024-04-25 08:25:46.389994553 +0200
++++ qtbase-opensource-src-5.15.2+dfsg/src/corelib/serialization/qxmlstream_p.h 
2024-04-25 08:25:46.385994556 +0200
+@@ -804,6 +804,17 @@
+ #endif
+     bool atEnd;
+ 
++    enum class XmlContext
++    {
++        Prolog,
++        Body,
++    };
++
++    XmlContext currentContext = XmlContext::Prolog;
++    bool foundDTD = false;
++    bool isValidToken(QXmlStreamReader::TokenType type);
++    void checkToken();
++
+     /*!
+       \sa setType()
+      */
diff -Nru qtbase-opensource-src-5.15.2+dfsg/debian/patches/CVE-2023-51714.diff 
qtbase-opensource-src-5.15.2+dfsg/debian/patches/CVE-2023-51714.diff
--- qtbase-opensource-src-5.15.2+dfsg/debian/patches/CVE-2023-51714.diff        
1970-01-01 01:00:00.000000000 +0100
+++ qtbase-opensource-src-5.15.2+dfsg/debian/patches/CVE-2023-51714.diff        
2024-04-28 22:48:02.000000000 +0200
@@ -0,0 +1,61 @@
+From 23c3fc483e8b6e21012a61f0bea884446f727776 Mon Sep 17 00:00:00 2001
+From: Marc Mutz <marc.m...@qt.io>
+Date: Tue, 12 Dec 2023 22:08:07 +0100
+Subject: [PATCH] HPack: fix incorrect integer overflow check
+
+This code never worked:
+
+For the comparison with max() - 32 to trigger, on 32-bit platforms (or
+Qt 5) signed interger overflow would have had to happen in the
+addition of the two sizes. The compiler can therefore remove the
+overflow check as dead code.
+
+On Qt 6 and 64-bit platforms, the signed integer addition would be
+very unlikely to overflow, but the following truncation to uint32
+would yield the correct result only in a narrow 32-value window just
+below UINT_MAX, if even that.
+
+Fix by using the proper tool, qAddOverflow.
+
+Manual conflict resolutions:
+ - qAddOverflow doesn't exist in Qt 5, use private add_overflow
+   predecessor API instead
+
+Change-Id: I7599f2e75ff7f488077b0c60b81022591005661c
+Reviewed-by: Allan Sandfeld Jensen <allan.jen...@qt.io>
+(cherry picked from commit ee5da1f2eaf8932aeca02ffea6e4c618585e29e3)
+Reviewed-by: Qt Cherry-pick Bot <cherrypick_...@qt-project.org>
+(cherry picked from commit debeb8878da2dc706ead04b6072ecbe7e5313860)
+Reviewed-by: Thiago Macieira <thiago.macie...@intel.com>
+Reviewed-by: Marc Mutz <marc.m...@qt.io>
+(cherry picked from commit 811b9eef6d08d929af8708adbf2a5effb0eb62d7)
+(cherry picked from commit f931facd077ce945f1e42eaa3bead208822d3e00)
+(cherry picked from commit 9ef4ca5ecfed771dab890856130e93ef5ceabef5)
+Reviewed-by: Mårten Nordheim <marten.nordh...@qt.io>
+---
+
+Index: 
qtbase-opensource-src-5.15.2+dfsg/src/network/access/http2/hpacktable.cpp
+===================================================================
+--- 
qtbase-opensource-src-5.15.2+dfsg.orig/src/network/access/http2/hpacktable.cpp  
   2024-04-24 16:05:41.491907436 +0200
++++ qtbase-opensource-src-5.15.2+dfsg/src/network/access/http2/hpacktable.cpp  
2024-04-24 16:07:20.779882496 +0200
+@@ -40,6 +40,7 @@
+ #include "hpacktable_p.h"
+ 
+ #include <QtCore/qdebug.h>
++#include <QtCore/private/qnumeric_p.h>
+ 
+ #include <algorithm>
+ #include <cstddef>
+@@ -62,8 +63,10 @@
+     // for counting the number of references to the name and value would have
+     // 32 octets of overhead."
+ 
+-    const unsigned sum = unsigned(name.size() + value.size());
+-    if (std::numeric_limits<unsigned>::max() - 32 < sum)
++    size_t sum;
++    if (add_overflow(size_t(name.size()), size_t(value.size()), &sum))
++        return HeaderSize();
++    if (sum > (std::numeric_limits<unsigned>::max() - 32))
+         return HeaderSize();
+     return HeaderSize(true, quint32(sum + 32));
+ }
diff -Nru qtbase-opensource-src-5.15.2+dfsg/debian/patches/CVE-2024-25580.diff 
qtbase-opensource-src-5.15.2+dfsg/debian/patches/CVE-2024-25580.diff
--- qtbase-opensource-src-5.15.2+dfsg/debian/patches/CVE-2024-25580.diff        
1970-01-01 01:00:00.000000000 +0100
+++ qtbase-opensource-src-5.15.2+dfsg/debian/patches/CVE-2024-25580.diff        
2024-02-27 23:25:41.000000000 +0100
@@ -0,0 +1,197 @@
+diff --git a/src/gui/util/qktxhandler.cpp b/src/gui/util/qktxhandler.cpp
+index 0d98e97453..6a79e55109 100644
+--- a/src/gui/util/qktxhandler.cpp
++++ b/src/gui/util/qktxhandler.cpp
+@@ -73,7 +73,7 @@ struct KTXHeader {
+     quint32 bytesOfKeyValueData;
+ };
+ 
+-static const quint32 headerSize = sizeof(KTXHeader);
++static constexpr quint32 qktxh_headerSize = sizeof(KTXHeader);
+ 
+ // Currently unused, declared for future reference
+ struct KTXKeyValuePairItem {
+@@ -103,11 +103,36 @@ struct KTXMipmapLevel {
+     */
+ };
+ 
+-bool QKtxHandler::canRead(const QByteArray &suffix, const QByteArray &block)
++static bool qAddOverflow(quint32 v1, quint32 v2, quint32 *r) {
++    // unsigned additions are well-defined
++    *r = v1 + v2;
++    return v1 > quint32(v1 + v2);
++}
++
++// Returns the nearest multiple of 4 greater than or equal to 'value'
++static bool nearestMultipleOf4(quint32 value, quint32 *result)
++{
++    constexpr quint32 rounding = 4;
++    *result = 0;
++    if (qAddOverflow(value, rounding - 1, result))
++        return true;
++    *result &= ~(rounding - 1);
++    return false;
++}
++
++// Returns a slice with prechecked bounds
++static QByteArray safeSlice(const QByteArray& array, quint32 start, quint32 
length)
+ {
+-    Q_UNUSED(suffix)
++    quint32 end = 0;
++    if (qAddOverflow(start, length, &end) || end > quint32(array.length()))
++        return {};
++    return QByteArray(array.data() + start, length);
++}
+ 
+-    return (qstrncmp(block.constData(), ktxIdentifier, KTX_IDENTIFIER_LENGTH) 
== 0);
++bool QKtxHandler::canRead(const QByteArray &suffix, const QByteArray &block)
++{
++    Q_UNUSED(suffix);
++    return block.startsWith(QByteArray::fromRawData(ktxIdentifier, 
KTX_IDENTIFIER_LENGTH));
+ }
+ 
+ QTextureFileData QKtxHandler::read()
+@@ -115,42 +140,97 @@ QTextureFileData QKtxHandler::read()
+     if (!device())
+         return QTextureFileData();
+ 
+-    QByteArray buf = device()->readAll();
+-    const quint32 dataSize = quint32(buf.size());
+-    if (dataSize < headerSize || !canRead(QByteArray(), buf)) {
+-        qCDebug(lcQtGuiTextureIO, "Invalid KTX file %s", 
logName().constData());
++    const QByteArray buf = device()->readAll();
++    if (size_t(buf.size()) > std::numeric_limits<quint32>::max()) {
++        qWarning(lcQtGuiTextureIO, "Too big KTX file %s", 
logName().constData());
++        return QTextureFileData();
++    }
++
++    if (!canRead(QByteArray(), buf)) {
++        qWarning(lcQtGuiTextureIO, "Invalid KTX file %s", 
logName().constData());
++        return QTextureFileData();
++    }
++
++    if (buf.size() < qsizetype(qktxh_headerSize)) {
++        qWarning(lcQtGuiTextureIO, "Invalid KTX header size in %s", 
logName().constData());
+         return QTextureFileData();
+     }
+ 
+-    const KTXHeader *header = reinterpret_cast<const KTXHeader 
*>(buf.constData());
+-    if (!checkHeader(*header)) {
+-        qCDebug(lcQtGuiTextureIO, "Unsupported KTX file format in %s", 
logName().constData());
++    KTXHeader header;
++    memcpy(&header, buf.data(), qktxh_headerSize);
++    if (!checkHeader(header)) {
++        qWarning(lcQtGuiTextureIO, "Unsupported KTX file format in %s", 
logName().constData());
+         return QTextureFileData();
+     }
+ 
+     QTextureFileData texData;
+     texData.setData(buf);
+ 
+-    texData.setSize(QSize(decode(header->pixelWidth), 
decode(header->pixelHeight)));
+-    texData.setGLFormat(decode(header->glFormat));
+-    texData.setGLInternalFormat(decode(header->glInternalFormat));
+-    texData.setGLBaseInternalFormat(decode(header->glBaseInternalFormat));
+-
+-    texData.setNumLevels(decode(header->numberOfMipmapLevels));
+-    quint32 offset = headerSize + decode(header->bytesOfKeyValueData);
+-    const int maxLevels = qMin(texData.numLevels(), 32);               // Cap 
iterations in case of corrupt file.
+-    for (int i = 0; i < maxLevels; i++) {
+-        if (offset + sizeof(KTXMipmapLevel) > dataSize)                // 
Corrupt file; avoid oob read
+-            break;
+-        const KTXMipmapLevel *level = reinterpret_cast<const KTXMipmapLevel 
*>(buf.constData() + offset);
+-        quint32 levelLen = decode(level->imageSize);
+-        texData.setDataOffset(offset + sizeof(KTXMipmapLevel::imageSize), i);
+-        texData.setDataLength(levelLen, i);
+-        offset += sizeof(KTXMipmapLevel::imageSize) + levelLen + (3 - 
((levelLen + 3) % 4));
++    texData.setSize(QSize(decode(header.pixelWidth), 
decode(header.pixelHeight)));
++    texData.setGLFormat(decode(header.glFormat));
++    texData.setGLInternalFormat(decode(header.glInternalFormat));
++    texData.setGLBaseInternalFormat(decode(header.glBaseInternalFormat));
++
++    texData.setNumLevels(decode(header.numberOfMipmapLevels));
++
++    const quint32 bytesOfKeyValueData = decode(header.bytesOfKeyValueData);
++    quint32 headerKeyValueSize;
++    if (qAddOverflow(qktxh_headerSize, bytesOfKeyValueData, 
&headerKeyValueSize)) {
++        qWarning(lcQtGuiTextureIO, "Overflow in size of key value data in 
header of KTX file %s",
++                 logName().constData());
++        return QTextureFileData();
++    }
++
++    if (headerKeyValueSize >= quint32(buf.size())) {
++        qWarning(lcQtGuiTextureIO, "OOB request in KTX file %s", 
logName().constData());
++        return QTextureFileData();
++    }
++
++    // Technically, any number of levels is allowed but if the value is 
bigger than
++    // what is possible in KTX V2 (and what makes sense) we return an error.
++    // maxLevels = log2(max(width, height, depth))
++    const int maxLevels = (sizeof(quint32) * 8)
++            - qCountLeadingZeroBits(std::max(
++                    { header.pixelWidth, header.pixelHeight, 
header.pixelDepth }));
++
++    if (texData.numLevels() > maxLevels) {
++        qWarning(lcQtGuiTextureIO, "Too many levels in KTX file %s", 
logName().constData());
++        return QTextureFileData();
++    }
++
++    quint32 offset = headerKeyValueSize;
++    for (int level = 0; level < texData.numLevels(); level++) {
++        const auto imageSizeSlice = safeSlice(buf, offset, sizeof(quint32));
++        if (imageSizeSlice.isEmpty()) {
++            qWarning(lcQtGuiTextureIO, "OOB request in KTX file %s", 
logName().constData());
++            return QTextureFileData();
++        }
++
++        const quint32 imageSize = 
decode(qFromUnaligned<quint32>(imageSizeSlice.data()));
++        offset += sizeof(quint32); // overflow checked indirectly above
++
++        texData.setDataOffset(offset, level);
++        texData.setDataLength(imageSize, level);
++
++        // Add image data and padding to offset
++        quint32 padded = 0;
++        if (nearestMultipleOf4(imageSize, &padded)) {
++            qWarning(lcQtGuiTextureIO, "Overflow in KTX file %s", 
logName().constData());
++            return QTextureFileData();
++        }
++
++        quint32 offsetNext;
++        if (qAddOverflow(offset, padded, &offsetNext)) {
++            qWarning(lcQtGuiTextureIO, "OOB request in KTX file %s", 
logName().constData());
++            return QTextureFileData();
++        }
++
++        offset = offsetNext;
+     }
+ 
+     if (!texData.isValid()) {
+-        qCDebug(lcQtGuiTextureIO, "Invalid values in header of KTX file %s", 
logName().constData());
++        qWarning(lcQtGuiTextureIO, "Invalid values in header of KTX file %s",
++                 logName().constData());
+         return QTextureFileData();
+     }
+ 
+@@ -191,7 +271,7 @@ bool QKtxHandler::checkHeader(const KTXHeader &header)
+             (decode(header.numberOfFaces) == 1));
+ }
+ 
+-quint32 QKtxHandler::decode(quint32 val)
++quint32 QKtxHandler::decode(quint32 val) const
+ {
+     return inverseEndian ? qbswap<quint32>(val) : val;
+ }
+diff --git a/src/gui/util/qktxhandler_p.h b/src/gui/util/qktxhandler_p.h
+index f831e59d95..cdf1b2eaf8 100644
+--- a/src/gui/util/qktxhandler_p.h
++++ b/src/gui/util/qktxhandler_p.h
+@@ -68,7 +68,7 @@ public:
+ 
+ private:
+     bool checkHeader(const KTXHeader &header);
+-    quint32 decode(quint32 val);
++    quint32 decode(quint32 val) const;
+ 
+     bool inverseEndian = false;
+ };
diff -Nru qtbase-opensource-src-5.15.2+dfsg/debian/patches/series 
qtbase-opensource-src-5.15.2+dfsg/debian/patches/series
--- qtbase-opensource-src-5.15.2+dfsg/debian/patches/series     2021-07-02 
17:58:04.000000000 +0200
+++ qtbase-opensource-src-5.15.2+dfsg/debian/patches/series     2024-04-28 
22:48:02.000000000 +0200
@@ -6,6 +6,19 @@
 mime_globs.diff
 fix-invalid-pointer-return-with-QGridLayout.diff
 
+CVE-2024-25580.diff
+CVE-2023-32763.diff
+CVE-2022-25255.diff
+CVE-2023-24607.diff
+sql_odbc_fix_unicode_check.diff
+sql_odbc_more_unicode_checks.diff
+CVE-2023-32762.diff
+CVE-2023-51714.diff
+CVE-2023-37369.diff
+CVE-2023-38197.diff
+CVE-2023-34410.diff
+CVE-2023-33285.diff
+
 # Debian specific.
 gnukfreebsd.diff
 no_htmlinfo_example.diff
diff -Nru 
qtbase-opensource-src-5.15.2+dfsg/debian/patches/sql_odbc_fix_unicode_check.diff
 
qtbase-opensource-src-5.15.2+dfsg/debian/patches/sql_odbc_fix_unicode_check.diff
--- 
qtbase-opensource-src-5.15.2+dfsg/debian/patches/sql_odbc_fix_unicode_check.diff
    1970-01-01 01:00:00.000000000 +0100
+++ 
qtbase-opensource-src-5.15.2+dfsg/debian/patches/sql_odbc_fix_unicode_check.diff
    2024-04-28 22:48:02.000000000 +0200
@@ -0,0 +1,24 @@
+Description: QSQL/ODBC: fix regression (trailing NUL)
+ When we fixed the callers of toSQLTCHAR() to use the result's size()
+ instead of the input's (which differ, if sizeof(SQLTCHAR) != 2), we
+ exposed callers to the append(0), which changes the size() of the
+ result QVLA. Callers that don't rely on NUL-termination (all?) now saw
+ an additional training NUL.
+ .
+ Fix by not NUL-terminating, and changing the only user of SQL_NTS to
+ use an explicit length.
+Origin: upstream, 
https://code.qt.io/cgit/qt/qtbase.git/commit/?id=9020034b3b6a3a81
+Last-Update: 2023-06-30
+
+Index: 
qtbase-opensource-src-5.15.2+dfsg/src/plugins/sqldrivers/odbc/qsql_odbc.cpp
+===================================================================
+--- 
qtbase-opensource-src-5.15.2+dfsg.orig/src/plugins/sqldrivers/odbc/qsql_odbc.cpp
   2024-04-28 17:51:58.976069584 +0200
++++ 
qtbase-opensource-src-5.15.2+dfsg/src/plugins/sqldrivers/odbc/qsql_odbc.cpp     
   2024-04-28 17:51:58.972069583 +0200
+@@ -125,7 +125,6 @@
+ {
+     QVarLengthArray<SQLTCHAR> result;
+     toSQLTCHARImpl(result, input);
+-    result.append(0); // make sure it's null terminated, doesn't matter if it 
already is, it does if it isn't.
+     return result;
+ }
+ 
diff -Nru 
qtbase-opensource-src-5.15.2+dfsg/debian/patches/sql_odbc_more_unicode_checks.diff
 
qtbase-opensource-src-5.15.2+dfsg/debian/patches/sql_odbc_more_unicode_checks.diff
--- 
qtbase-opensource-src-5.15.2+dfsg/debian/patches/sql_odbc_more_unicode_checks.diff
  1970-01-01 01:00:00.000000000 +0100
+++ 
qtbase-opensource-src-5.15.2+dfsg/debian/patches/sql_odbc_more_unicode_checks.diff
  2024-04-28 22:48:02.000000000 +0200
@@ -0,0 +1,37 @@
+Description: SQL/ODBC: add another check to detect unicode availability in 
driver
+ Since ODBC does not have a direct way finding out if unicode is
+ supported by the underlying driver the ODBC plugin does some checks. As
+ a last resort a sql statement is executed which returns a string. But
+ even this may fail because the select statement has no FROM part which
+ is rejected by at least Oracle does not allow. Therefore add another
+ query which is correct for Oracle & DB2 as a workaround. The question
+ why the first three statements to check for unicode availability fail
+ is still open but can't be checked since I've no access to an oracle
+ database.
+Origin: upstream, 
https://code.qt.io/cgit/qt/qtbase.git/commit/?id=f19320748d282b1e
+Last-Update: 2023-06-30
+
+Index: 
qtbase-opensource-src-5.15.2+dfsg/src/plugins/sqldrivers/odbc/qsql_odbc.cpp
+===================================================================
+--- 
qtbase-opensource-src-5.15.2+dfsg.orig/src/plugins/sqldrivers/odbc/qsql_odbc.cpp
   2024-04-28 17:59:07.172222178 +0200
++++ 
qtbase-opensource-src-5.15.2+dfsg/src/plugins/sqldrivers/odbc/qsql_odbc.cpp     
   2024-04-28 17:59:07.172222178 +0200
+@@ -2109,7 +2109,18 @@
+                                   hDbc,
+                                   &hStmt);
+ 
+-    r = SQLExecDirect(hStmt, toSQLTCHAR(QLatin1String("select 
'test'")).data(), SQL_NTS);
++    // for databases which do not return something useful in SQLGetInfo and 
are picky about a
++    // 'SELECT' statement without 'FROM' but support VALUE(foo) statement 
like e.g. DB2 or Oracle
++    const auto statements = {
++        QLatin1String("select 'test'"),
++        QLatin1String("values('test')"),
++        QLatin1String("select 'test' from dual"),
++    };
++    for (const auto &statement : statements) {
++        r = SQLExecDirect(hStmt, toSQLTCHAR(statement).data(), SQL_NTS);
++        if (r == SQL_SUCCESS)
++            break;
++    }
+     if(r == SQL_SUCCESS) {
+         r = SQLFetch(hStmt);
+         if(r == SQL_SUCCESS) {

--- End Message ---
--- Begin Message ---
Version: 11.10

The upload requested in this bug has been released as part of 11.10.

--- End Message ---

Reply via email to