[neon/qt/qtbase/Neon/release] debian/patches: manually sync to debian patches

Carlos De Maine null at kde.org
Fri Jul 14 01:59:26 BST 2023


Git commit d027d07b3374a0f446b4b4ef734f8ec78c98ceae by Carlos De Maine.
Committed on 14/07/2023 at 00:48.
Pushed by carlosdem into branch 'Neon/release'.

manually sync to debian patches

D  +0    -38   debian/patches/CVE-2021-38593.diff
D  +0    -92   debian/patches/CVE-2022-25255.diff
A  +330  -0    debian/patches/CVE-2023-24607.diff
A  +18   -0    debian/patches/CVE-2023-32762.diff
A  +50   -0    debian/patches/CVE-2023-32763.diff
A  +77   -0    debian/patches/CVE-2023-33285.diff
A  +34   -0    debian/patches/CVE-2023-34410.diff
A  +31   -0    debian/patches/a11y_root.diff
A  +39   -0    debian/patches/dont_use_O_PATH.diff
A  +80   -0    debian/patches/fix_alt_backtick.diff
A  +32   -0    debian/patches/fix_qdbusmacros_h.diff
D  +0    -58   debian/patches/fix_recursion_crash.diff
A  +27   -0    debian/patches/fusion_checkable_qpushbutton.diff
A  +25   -0    debian/patches/gnome_wayland.diff
A  +66   -0    debian/patches/image_deletion_order.diff
D  +0    -80   debian/patches/mysql_field_readonly.diff
A  +79   -0    debian/patches/openssl_set_options.diff
A  +60   -0    debian/patches/qmenu_set_transient_parent.diff
A  +25   -0    debian/patches/qshapedpixmapwindow_no_tooltip.diff
A  +44   -0    debian/patches/qxcbwindow_set_geometry.diff
D  +0    -50   debian/patches/remove_limit_on_number_of_streams.diff
A  +102  -0    debian/patches/revert_startBlocking_removal.diff
M  +19   -9    debian/patches/series
A  +32   -0    debian/patches/sql_odbc_fix_unicode_check.diff
A  +35   -0    debian/patches/sql_odbc_more_unicode_checks.diff
D  +0    -18   debian/patches/xdg_filechooser_portal_send_window_id_in_hex.diff

https://invent.kde.org/neon/qt/qtbase/-/commit/d027d07b3374a0f446b4b4ef734f8ec78c98ceae

diff --git a/debian/patches/CVE-2021-38593.diff b/debian/patches/CVE-2021-38593.diff
deleted file mode 100644
index c80e5c91..00000000
--- a/debian/patches/CVE-2021-38593.diff
+++ /dev/null
@@ -1,38 +0,0 @@
-Description: improve fix for avoiding huge number of tiny dashes
- Some pathological cases were not caught by the previous fix.
-Origin: upstream, commits:
- https://code.qt.io/cgit/qt/qtbase.git/commit/?id=6b400e3147dcfd8c
- https://code.qt.io/cgit/qt/qtbase.git/commit/?id=84aba80944a2e1c3
- https://code.qt.io/cgit/qt/qtbase.git/commit/?id=cca8ed0547405b1c
-Last-Update: 2022-06-20
-
---- a/src/gui/painting/qpaintengineex.cpp
-+++ b/src/gui/painting/qpaintengineex.cpp
-@@ -388,7 +388,7 @@ Q_GUI_EXPORT extern bool qt_scaleForTran
- void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &inPen)
- {
- #ifdef QT_DEBUG_DRAW
--    qDebug() << "QPaintEngineEx::stroke()" << pen;
-+    qDebug() << "QPaintEngineEx::stroke()" << inPen;
- #endif
- 
-     Q_D(QPaintEngineEx);
-@@ -415,15 +415,15 @@ void QPaintEngineEx::stroke(const QVecto
-             clipRect = xf.inverted().mapRect(QRectF(d->exDeviceRect));
-         }
-         // Check to avoid generating unwieldy amount of dashes that will not be visible anyway
--        QRectF extentRect = cpRect & clipRect;
-+        qreal pw = pen.widthF() ? pen.widthF() : 1;
-+        QRectF extentRect = cpRect.adjusted(-pw, -pw, pw, pw) & clipRect;
-         qreal extent = qMax(extentRect.width(), extentRect.height());
-         qreal patternLength = 0;
-         const QVector<qreal> pattern = pen.dashPattern();
-         const int patternSize = qMin(pattern.size(), 32);
-         for (int i = 0; i < patternSize; i++)
-             patternLength += qMax(pattern.at(i), qreal(0));
--        if (pen.widthF())
--            patternLength *= pen.widthF();
-+        patternLength *= pw;
-         if (qFuzzyIsNull(patternLength)) {
-             pen.setStyle(Qt::NoPen);
-         } else if (extent / patternLength > 10000) {
diff --git a/debian/patches/CVE-2022-25255.diff b/debian/patches/CVE-2022-25255.diff
deleted file mode 100644
index c9687c09..00000000
--- a/debian/patches/CVE-2022-25255.diff
+++ /dev/null
@@ -1,92 +0,0 @@
-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
-
---- a/src/corelib/io/qprocess_unix.cpp
-+++ b/src/corelib/io/qprocess_unix.cpp
-@@ -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 @@ void QProcessPrivate::startProcess()
-     // 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 @@ bool QProcessPrivate::startDetached(qint
-                 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);
---- a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
-+++ b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
-@@ -1498,7 +1498,7 @@ void tst_QApplication::desktopSettingsAw
-     environment += QLatin1String("QT_MAC_DISABLE_FOREGROUND_APPLICATION_TRANSFORM=1");
-     testProcess.setEnvironment(environment);
- #endif
--    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));
-@@ -2452,7 +2452,7 @@ void tst_QApplication::qtbug_12673()
- #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 --git a/debian/patches/CVE-2023-24607.diff b/debian/patches/CVE-2023-24607.diff
new file mode 100644
index 00000000..a7977dcb
--- /dev/null
+++ b/debian/patches/CVE-2023-24607.diff
@@ -0,0 +1,330 @@
+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
+
+--- a/src/plugins/sqldrivers/odbc/qsql_odbc.cpp
++++ b/src/plugins/sqldrivers/odbc/qsql_odbc.cpp
+@@ -92,23 +92,39 @@ inline static QString fromSQLTCHAR(const
+     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 @@ QChar QODBCDriverPrivate::quoteChar()
+     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 @@ bool QODBCDriverPrivate::setConnectionOp
+             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 @@ bool QODBCDriverPrivate::setConnectionOp
+             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 @@ bool QODBCResult::reset (const QString&
+         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));
+@@ -1371,9 +1392,12 @@ bool QODBCResult::prepare(const QString&
+         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",
+@@ -1401,7 +1425,7 @@ bool QODBCResult::exec()
+         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));
+ 
+@@ -1580,35 +1604,36 @@ bool QODBCResult::exec()
+             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;
+@@ -1716,10 +1741,11 @@ bool QODBCResult::exec()
+             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;
+                 }
+@@ -1966,14 +1992,16 @@ bool QODBCDriver::open(const QString & d
+     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));
+@@ -2352,17 +2380,15 @@ QStringList QODBCDriver::tables(QSql::Ta
+     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);
+@@ -2436,28 +2462,30 @@ QSqlIndex QODBCDriver::primaryIndex(cons
+                         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);
+@@ -2538,15 +2566,17 @@ QSqlRecord QODBCDriver::record(const QSt
+                         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 --git a/debian/patches/CVE-2023-32762.diff b/debian/patches/CVE-2023-32762.diff
new file mode 100644
index 00000000..ef4376da
--- /dev/null
+++ b/debian/patches/CVE-2023-32762.diff
@@ -0,0 +1,18 @@
+Description: hsts: match header names case insensitively
+ Header field names are always considered to be case-insensitive.
+Origin: upstream, https://download.qt.io/official_releases/qt/5.15/CVE-2023-32762-qtbase-5.15.diff
+Last-Update: 2023-05-22
+
+--- a/src/network/access/qhsts.cpp
++++ b/src/network/access/qhsts.cpp
+@@ -364,8 +364,8 @@ quoted-pair    = "\" CHAR
+ 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:
+             //
diff --git a/debian/patches/CVE-2023-32763.diff b/debian/patches/CVE-2023-32763.diff
new file mode 100644
index 00000000..3de1b412
--- /dev/null
+++ b/debian/patches/CVE-2023-32763.diff
@@ -0,0 +1,50 @@
+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
+
+--- a/src/gui/painting/qfixed_p.h
++++ b/src/gui/painting/qfixed_p.h
+@@ -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<(i
+ 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(); }
+--- a/src/gui/text/qtextlayout.cpp
++++ b/src/gui/text/qtextlayout.cpp
+@@ -2150,11 +2150,14 @@ found:
+         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 --git a/debian/patches/CVE-2023-33285.diff b/debian/patches/CVE-2023-33285.diff
new file mode 100644
index 00000000..9eadaf64
--- /dev/null
+++ b/debian/patches/CVE-2023-33285.diff
@@ -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 --git a/debian/patches/CVE-2023-34410.diff b/debian/patches/CVE-2023-34410.diff
new file mode 100644
index 00000000..bc5e30dd
--- /dev/null
+++ b/debian/patches/CVE-2023-34410.diff
@@ -0,0 +1,34 @@
+Description: Ssl: Copy the on-demand cert loading bool from default config
+ Otherwise individual sockets will still load system certificates when
+ a chain doesn't match against the configured CA certificates.
+ That's not intended behavior, since specifically setting the CA
+ certificates means you don't want the system certificates to be used.
+ .
+ This is potentially a breaking change because now, if you ever add a
+ CA to the default config, it will disable loading system certificates
+ on demand for all sockets. And the only way to re-enable it is to
+ create a null-QSslConfiguration and set it as the new default.
+Origin: upstream, https://code.qt.io/cgit/qt/qtbase.git/commit/?id=57ba6260c0801055
+Last-Update: 2023-06-08
+
+--- a/src/network/ssl/qsslsocket.cpp
++++ b/src/network/ssl/qsslsocket.cpp
+@@ -2221,6 +2221,10 @@ QSslSocketPrivate::QSslSocketPrivate()
+     , 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 @@ void QSslConfigurationPrivate::deepCopyD
+     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 --git a/debian/patches/a11y_root.diff b/debian/patches/a11y_root.diff
new file mode 100644
index 00000000..0a770c95
--- /dev/null
+++ b/debian/patches/a11y_root.diff
@@ -0,0 +1,31 @@
+Description: fix accessibility on XCB when running as root
+ Accessibility actually works when running applications as root, but we
+ would never properly connect, since the enabledChanged signal would be
+ emitted from the constructor in this case. So after connecting the
+ signal, check the value by hand to make sure not to miss the
+ notification.
+ .
+ Only applications running as root would be affected, because all other
+ applications would go through the asynchronous pattern of getting the
+ bus address from dbus instead.
+Origin: upstream, https://code.qt.io/cgit/qt/qtbase.git/commit/?id=db346e711c9af505
+Bug: https://bugs.debian.org/1033995
+Last-Update: 2023-04-15
+
+--- a/src/platformsupport/linuxaccessibility/bridge.cpp
++++ b/src/platformsupport/linuxaccessibility/bridge.cpp
+@@ -65,6 +65,14 @@ QSpiAccessibleBridge::QSpiAccessibleBrid
+ {
+     dbusConnection = new DBusConnection();
+     connect(dbusConnection, SIGNAL(enabledChanged(bool)), this, SLOT(enabledChanged(bool)));
++    // Now that we have connected the signal, make sure we didn't miss a change,
++    // e.g. when running as root or when AT_SPI_BUS_ADDRESS is set by hand.
++    // But do that only on next loop, once dbus is really settled.
++    QTimer::singleShot(
++        0, this, [this]{
++            if (dbusConnection->isEnabled())
++                enabledChanged(true);
++        });
+ }
+ 
+ void QSpiAccessibleBridge::enabledChanged(bool enabled)
diff --git a/debian/patches/dont_use_O_PATH.diff b/debian/patches/dont_use_O_PATH.diff
new file mode 100644
index 00000000..2a2a8caf
--- /dev/null
+++ b/debian/patches/dont_use_O_PATH.diff
@@ -0,0 +1,39 @@
+Description: OpenFile portal: do not use O_PATH fds
+ Using O_PATH requires correctly specifying whether the fd is writable or
+ not. Stating that the fd is writable without it actually being writable
+ results into rejection on xdg-desktop-portal side. Other implementations
+ like xdg-open or gtk have also moved away from O_PATH fds so this will
+ make a matching implementation and avoid possible rejections from xdp.
+Origin: upstream, https://code.qt.io/cgit/qt/qtbase.git/commit/?id=03cbcba7b2b0e42a
+Last-Update: 2023-05-13
+
+--- a/src/platformsupport/services/genericunix/qgenericunixservices.cpp
++++ b/src/platformsupport/services/genericunix/qgenericunixservices.cpp
+@@ -203,8 +203,7 @@ static inline QDBusMessage xdgDesktopPor
+     // handle_token (s) -  A string that will be used as the last element of the @handle.
+     // writable (b) - Whether to allow the chosen application to write to the file.
+ 
+-#ifdef O_PATH
+-    const int fd = qt_safe_open(QFile::encodeName(url.toLocalFile()), O_PATH);
++    const int fd = qt_safe_open(QFile::encodeName(url.toLocalFile()), O_RDONLY);
+     if (fd != -1) {
+         QDBusMessage message = QDBusMessage::createMethodCall(QLatin1String("org.freedesktop.portal.Desktop"),
+                                                               QLatin1String("/org/freedesktop/portal/desktop"),
+@@ -214,16 +213,13 @@ static inline QDBusMessage xdgDesktopPor
+         QDBusUnixFileDescriptor descriptor;
+         descriptor.giveFileDescriptor(fd);
+ 
+-        const QVariantMap options = {{QLatin1String("writable"), true}};
++        const QVariantMap options = {};
+ 
+         // FIXME parent_window_id
+         message << QString() << QVariant::fromValue(descriptor) << options;
+ 
+         return QDBusConnection::sessionBus().call(message);
+     }
+-#else
+-    Q_UNUSED(url)
+-#endif
+ 
+     return QDBusMessage::createError(QDBusError::InternalError, qt_error_string());
+ }
diff --git a/debian/patches/fix_alt_backtick.diff b/debian/patches/fix_alt_backtick.diff
new file mode 100644
index 00000000..cd094c00
--- /dev/null
+++ b/debian/patches/fix_alt_backtick.diff
@@ -0,0 +1,80 @@
+Description: fix Alt+` shortcut on non-US layouts
+ Make it possible for non-letter-keys with Latin 1 symbols (`, !, @ etc.)
+ to participate in shortcuts also, when the keys generate national
+ symbols on non-Latin layout.
+ .
+ For example, in Russian layout, "`" key generates cyrillic "ё" letter of
+ national alphabet, so shortcuts with the key should still work
+ regardless of the actual layout.
+Origin: upstream, https://code.qt.io/cgit/qt/qtbase.git/commit?id=62e697fd568f6acd
+Last-Update: 2022-12-03
+
+--- a/src/platformsupport/input/xkbcommon/qxkbcommon.cpp
++++ b/src/platformsupport/input/xkbcommon/qxkbcommon.cpp
+@@ -471,7 +471,7 @@ QVector<xkb_keysym_t> QXkbCommon::toKeys
+     } else if (event->modifiers() & Qt::KeypadModifier) {
+         if (qtKey >= Qt::Key_0 && qtKey <= Qt::Key_9)
+             keysyms.append(XKB_KEY_KP_0 + (qtKey - Qt::Key_0));
+-    } else if (isLatin(qtKey) && event->text().isUpper()) {
++    } else if (isLatin1(qtKey) && event->text().isUpper()) {
+         keysyms.append(qtKey);
+     }
+ 
+@@ -523,7 +523,7 @@ int QXkbCommon::keysymToQtKey(xkb_keysym
+         // With standard shortcuts we should prefer a latin character, this is
+         // for checks like "some qkeyevent == QKeySequence::Copy" to work even
+         // when using for example 'russian' keyboard layout.
+-        if (!QXkbCommon::isLatin(keysym)) {
++        if (!QXkbCommon::isLatin1(keysym)) {
+             xkb_keysym_t latinKeysym = QXkbCommon::lookupLatinKeysym(state, code);
+             if (latinKeysym != XKB_KEY_NoSymbol)
+                 keysym = latinKeysym;
+@@ -546,7 +546,7 @@ static int keysymToQtKey_internal(xkb_ke
+     } else if (keysym >= XKB_KEY_KP_0 && keysym <= XKB_KEY_KP_9) {
+         // numeric keypad keys
+         qtKey = Qt::Key_0 + (keysym - XKB_KEY_KP_0);
+-    } else if (QXkbCommon::isLatin(keysym)) {
++    } else if (QXkbCommon::isLatin1(keysym)) {
+         qtKey = QXkbCommon::qxkbcommon_xkb_keysym_to_upper(keysym);
+     } else {
+         // check if we have a direct mapping
+@@ -678,7 +678,7 @@ QList<int> QXkbCommon::possibleKeys(xkb_
+         Qt::KeyboardModifiers neededMods = ModsTbl[i];
+         if ((modifiers & neededMods) == neededMods) {
+             if (i == 8) {
+-                if (isLatin(baseQtKey))
++                if (isLatin1(baseQtKey))
+                     continue;
+                 // add a latin key as a fall back key
+                 sym = lookupLatinKeysym(state, keycode);
+@@ -733,7 +733,7 @@ void QXkbCommon::verifyHasLatinLayout(xk
+     for (xkb_layout_index_t layout = 0; layout < layoutCount; ++layout) {
+         for (xkb_keycode_t code = minKeycode; code < maxKeycode; ++code) {
+             xkb_keymap_key_get_syms_by_level(keymap, code, layout, 0, &keysyms);
+-            if (keysyms && isLatin(keysyms[0]))
++            if (keysyms && isLatin1(keysyms[0]))
+                 nrLatinKeys++;
+             if (nrLatinKeys > 10) // arbitrarily chosen threshold
+                 return;
+@@ -766,7 +766,7 @@ xkb_keysym_t QXkbCommon::lookupLatinKeys
+         xkb_level_index_t level = xkb_state_key_get_level(state, keycode, layout);
+         if (xkb_keymap_key_get_syms_by_level(keymap, keycode, layout, level, &syms) != 1)
+             continue;
+-        if (isLatin(syms[0])) {
++        if (isLatin1(syms[0])) {
+             sym = syms[0];
+             break;
+         }
+--- a/src/platformsupport/input/xkbcommon/qxkbcommon_p.h
++++ b/src/platformsupport/input/xkbcommon/qxkbcommon_p.h
+@@ -94,8 +94,8 @@ public:
+     static void verifyHasLatinLayout(xkb_keymap *keymap);
+     static xkb_keysym_t lookupLatinKeysym(xkb_state *state, xkb_keycode_t keycode);
+ 
+-    static bool isLatin(xkb_keysym_t sym) {
+-        return ((sym >= 'a' && sym <= 'z') || (sym >= 'A' && sym <= 'Z'));
++    static bool isLatin1(xkb_keysym_t sym) {
++        return sym <= 0xff;
+     }
+     static bool isKeypad(xkb_keysym_t sym) {
+         return sym >= XKB_KEY_KP_Space && sym <= XKB_KEY_KP_9;
diff --git a/debian/patches/fix_qdbusmacros_h.diff b/debian/patches/fix_qdbusmacros_h.diff
new file mode 100644
index 00000000..563df7f2
--- /dev/null
+++ b/debian/patches/fix_qdbusmacros_h.diff
@@ -0,0 +1,32 @@
+Description: fix capitalization error in auto-generated qdbusmacros.h include
+Origin: upstream, https://code.qt.io/cgit/qt/qtbase.git/commit/?id=dca0304c26012a57
+Last-Update: 2023-05-13
+
+--- a/include/QtDBus/qdbusmacros.h
++++ b/include/QtDBus/qdbusmacros.h
+@@ -1,11 +1,11 @@
+ #ifndef DEPRECATED_HEADER_QtDBus_qdbusmacros_h
+ #define DEPRECATED_HEADER_QtDBus_qdbusmacros_h
+ #if defined(__GNUC__)
+-#  warning Header <QtDBus/qdbusmacros.h> is deprecated. Please include <QtDbus/qtdbusglobal.h> instead.
++#  warning Header <QtDBus/qdbusmacros.h> is deprecated. Please include <QtDBus/qtdbusglobal.h> instead.
+ #elif defined(_MSC_VER)
+-#  pragma message ("Header <QtDBus/qdbusmacros.h> is deprecated. Please include <QtDbus/qtdbusglobal.h> instead.")
++#  pragma message ("Header <QtDBus/qdbusmacros.h> is deprecated. Please include <QtDBus/qtdbusglobal.h> instead.")
+ #endif
+-#include <QtDbus/qtdbusglobal.h>
++#include <QtDBus/qtdbusglobal.h>
+ #if 0
+ #pragma qt_no_master_include
+ #endif
+--- a/sync.profile
++++ b/sync.profile
+@@ -77,7 +77,7 @@
+         "qsql.h" => "QtSql/qtsqlglobal.h"
+     },
+     "QtDBus" => {
+-        "qdbusmacros.h" => "QtDbus/qtdbusglobal.h"
++        "qdbusmacros.h" => "QtDBus/qtdbusglobal.h"
+     },
+     "QtTest" => {
+         "qtest_global.h" => "QtTest/qttestglobal.h"
diff --git a/debian/patches/fix_recursion_crash.diff b/debian/patches/fix_recursion_crash.diff
deleted file mode 100644
index 91176014..00000000
--- a/debian/patches/fix_recursion_crash.diff
+++ /dev/null
@@ -1,58 +0,0 @@
-Description: fix recursion crash when calling setStyleSheet with qproperty-styleSheet
- When calling setStyleSheet with property qproperty-styleSheet,
- QStyleSheetStyle::polish will call QStyleSheetStyle::setProperties,
- and then QStyleSheetStyle::setProperties goes on to call setProperty.
- Because there is property qproperty-styleSheet, it will update
- stylesheet by calling QStyleSheetStyle::polish.
- This causes the recursive call to crash.
-Origin: upstream, https://code.qt.io/cgit/qt/qtbase.git/commit/?id=e9cdcc7cb314586a
-Last-Update: 2021-11-13
-
---- a/src/widgets/styles/qstylesheetstyle.cpp
-+++ b/src/widgets/styles/qstylesheetstyle.cpp
-@@ -2649,6 +2649,9 @@ void QStyleSheetStyle::setProperties(QWi
-         default: v = decl.d->values.at(0).variant; break;
-         }
- 
-+        if (propertyL1 == QByteArray("styleSheet") && value == v)
-+            continue;
-+
-         w->setProperty(propertyL1, v);
-     }
- }
-Index: qtbase/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp
-===================================================================
---- qtbase.orig/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp
-+++ qtbase/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp
-@@ -94,6 +94,7 @@ private slots:
-     void layoutSpacing();
- #endif
-     void qproperty();
-+    void qproperty_styleSheet();
-     void palettePropagation_data();
-     void palettePropagation();
-     void fontPropagation_data();
-@@ -678,6 +679,23 @@ void tst_QStyleSheetStyle::qproperty()
-     QCOMPARE(pb.isChecked(), false);
- }
- 
-+void tst_QStyleSheetStyle::qproperty_styleSheet()
-+{
-+    QWidget w;
-+    auto checkBox = new QCheckBox("check", &w);
-+    QString sheet = R"(QCheckBox { qproperty-styleSheet: "QCheckBox { qproperty-text: foobar; }"; })";
-+
-+    QVERIFY(w.property("styleSheet").toString().isEmpty());
-+
-+    w.setStyleSheet(sheet);
-+    QCOMPARE(checkBox->text(), "check");
-+
-+    //recursion crash
-+    w.ensurePolished();
-+    QCOMPARE(w.property("styleSheet").toString(), sheet);
-+    QCOMPARE(checkBox->text(), "foobar");
-+}
-+
- namespace ns {
-     class PushButton1 : public QPushButton {
-         Q_OBJECT
diff --git a/debian/patches/fusion_checkable_qpushbutton.diff b/debian/patches/fusion_checkable_qpushbutton.diff
new file mode 100644
index 00000000..239cc386
--- /dev/null
+++ b/debian/patches/fusion_checkable_qpushbutton.diff
@@ -0,0 +1,27 @@
+Description: QPushButton/fusion style: don't ignore QIcon::On icon
+ The fusion style did ignore the QIcon::On icon because it reset
+ State_On to avoid the visual shift of a pressed button.
+ But it's not needed to reset this flag - the shift does not happen
+ because the fusion style does return 0 as offset for
+ PM_ButtonShiftHorizontal/PM_ButtonShiftVertical so no shifting will
+ happen.
+Origin: upstream, https://code.qt.io/cgit/qt/qtbase.git/commit/?id=e9ccdf4d84157173
+Last-Update: 2021-08-10
+
+--- a/src/widgets/styles/qfusionstyle.cpp
++++ b/src/widgets/styles/qfusionstyle.cpp
+@@ -1772,14 +1772,6 @@ void QFusionStyle::drawControl(ControlEl
+             proxy()->drawControl(CE_PushButtonLabel, &subopt, painter, widget);
+         }
+         break;
+-    case CE_PushButtonLabel:
+-        if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+-            QStyleOptionButton b(*button);
+-            // no PM_ButtonShiftHorizontal and PM_ButtonShiftVertical for fusion style
+-            b.state &= ~(State_On | State_Sunken);
+-            QCommonStyle::drawControl(element, &b, painter, widget);
+-        }
+-        break;
+     case CE_MenuBarEmptyArea:
+         painter->save();
+     {
diff --git a/debian/patches/gnome_wayland.diff b/debian/patches/gnome_wayland.diff
new file mode 100644
index 00000000..9f7375c7
--- /dev/null
+++ b/debian/patches/gnome_wayland.diff
@@ -0,0 +1,25 @@
+Description: use wayland platform plugin on GNOME wayland sessions by default
+ Qt wayland platform plugin has improved quite a lot and it is now pretty
+ much usable on Gnome. It also improves user experience a lot on HiDPI
+ displays.
+Origin: upstream, https://code.qt.io/cgit/qt/qtbase.git/commit/?id=dda7dab8274991e4
+Last-Update: 2022-10-16
+
+--- a/src/gui/kernel/qguiapplication.cpp
++++ b/src/gui/kernel/qguiapplication.cpp
+@@ -1412,14 +1412,7 @@ void QGuiApplicationPrivate::createPlatf
+         if (sessionType == QByteArrayLiteral("x11") && !platformName.contains(QByteArrayLiteral("xcb"))) {
+             platformName = QByteArrayLiteral("xcb");
+         } else if (sessionType == QByteArrayLiteral("wayland") && !platformName.contains(QByteArrayLiteral("wayland"))) {
+-            QByteArray currentDesktop = qgetenv("XDG_CURRENT_DESKTOP").toLower();
+-            QByteArray sessionDesktop = qgetenv("XDG_SESSION_DESKTOP").toLower();
+-            if (currentDesktop.contains("gnome") || sessionDesktop.contains("gnome")) {
+-                qInfo() << "Warning: Ignoring XDG_SESSION_TYPE=wayland on Gnome."
+-                        << "Use QT_QPA_PLATFORM=wayland to run on Wayland anyway.";
+-            } else {
+-                platformName = QByteArrayLiteral("wayland");
+-            }
++            platformName = QByteArrayLiteral("wayland");
+         }
+     }
+ #ifdef QT_QPA_DEFAULT_PLATFORM_NAME
diff --git a/debian/patches/image_deletion_order.diff b/debian/patches/image_deletion_order.diff
new file mode 100644
index 00000000..b20f5cb0
--- /dev/null
+++ b/debian/patches/image_deletion_order.diff
@@ -0,0 +1,66 @@
+Description: fix deletion order in QImageReader/Writer destructors
+ The device would be deleted before the image format handler, and hence
+ be a dangling pointer that could easily cause a crash if the handler
+ or codec would access it on destruction, e.g. for cleanup.
+Origin: upstream, commits
+ https://code.qt.io/cgit/qt/qtbase.git/commit/?id=f091026be1deb4b4
+ https://code.qt.io/cgit/qt/qtbase.git/commit/?id=5633cb69f68ca3d3
+Last-Update: 2023-02-26
+
+--- a/src/gui/image/qimagereader.cpp
++++ b/src/gui/image/qimagereader.cpp
+@@ -515,9 +515,9 @@ QImageReaderPrivate::QImageReaderPrivate
+ */
+ QImageReaderPrivate::~QImageReaderPrivate()
+ {
++    delete handler;
+     if (deleteDevice)
+         delete device;
+-    delete handler;
+ }
+ 
+ /*!
+@@ -774,12 +774,12 @@ bool QImageReader::decideFormatFromConte
+ */
+ void QImageReader::setDevice(QIODevice *device)
+ {
++    delete d->handler;
++    d->handler = nullptr;
+     if (d->device && d->deleteDevice)
+         delete d->device;
+     d->device = device;
+     d->deleteDevice = false;
+-    delete d->handler;
+-    d->handler = nullptr;
+     d->text.clear();
+ }
+ 
+--- a/src/gui/image/qimagewriter.cpp
++++ b/src/gui/image/qimagewriter.cpp
+@@ -349,9 +349,9 @@ QImageWriter::QImageWriter(const QString
+ */
+ QImageWriter::~QImageWriter()
+ {
++    delete d->handler;
+     if (d->deleteDevice)
+         delete d->device;
+-    delete d->handler;
+     delete d;
+ }
+ 
+@@ -396,13 +396,13 @@ QByteArray QImageWriter::format() const
+ */
+ void QImageWriter::setDevice(QIODevice *device)
+ {
++    delete d->handler;
++    d->handler = nullptr;
+     if (d->device && d->deleteDevice)
+         delete d->device;
+ 
+     d->device = device;
+     d->deleteDevice = false;
+-    delete d->handler;
+-    d->handler = nullptr;
+ }
+ 
+ /*!
diff --git a/debian/patches/mysql_field_readonly.diff b/debian/patches/mysql_field_readonly.diff
deleted file mode 100644
index c33b7524..00000000
--- a/debian/patches/mysql_field_readonly.diff
+++ /dev/null
@@ -1,80 +0,0 @@
-Description: treat the MYSQL_FIELD as read-only
- The MariaDB-connector-c version 3.2 and MariaDB server version 10.6
- cooperate to avoid re-transferring the query metadata, so the fact that
- we were modifying it was causing it to improperly decode the DATETIME
- data types into string, as we had asked. We ended up with a 7-byte
- string that was actually the date binary-encoded.
-Origin: upstream, https://code.qt.io/cgit/qt/qtbase.git/commit/?id=549ee216fd5bf2b3
-Last-Update: 2021-11-13
-
---- a/src/plugins/sqldrivers/mysql/qsql_mysql.cpp
-+++ b/src/plugins/sqldrivers/mysql/qsql_mysql.cpp
-@@ -223,7 +223,7 @@ public:
-     struct QMyField
-     {
-         char *outField = nullptr;
--        MYSQL_FIELD *myField = nullptr;
-+        const MYSQL_FIELD *myField = nullptr;
-         QMetaType::Type type = QMetaType::UnknownType;
-         my_bool nullIndicator = false;
-         ulong bufLength = 0ul;
-@@ -361,11 +361,10 @@ static bool qIsInteger(int t)
- void QMYSQLResultPrivate::bindBlobs()
- {
-     int i;
--    MYSQL_FIELD *fieldInfo;
-     MYSQL_BIND *bind;
- 
-     for(i = 0; i < fields.count(); ++i) {
--        fieldInfo = fields.at(i).myField;
-+        const MYSQL_FIELD *fieldInfo = fields.at(i).myField;
-         if (qIsBlob(inBinds[i].buffer_type) && meta && fieldInfo) {
-             bind = &inBinds[i];
-             bind->buffer_length = fieldInfo->max_length;
-@@ -392,35 +391,34 @@ bool QMYSQLResultPrivate::bindInValues()
-     inBinds = new MYSQL_BIND[fields.size()];
-     memset(inBinds, 0, fields.size() * sizeof(MYSQL_BIND));
- 
--    MYSQL_FIELD *fieldInfo;
-+    const MYSQL_FIELD *fieldInfo;
- 
-     while((fieldInfo = mysql_fetch_field(meta))) {
-+        MYSQL_BIND *bind = &inBinds[i];
-+
-         QMyField &f = fields[i];
-         f.myField = fieldInfo;
--
-+        bind->buffer_length = f.bufLength = fieldInfo->length + 1;
-+        bind->buffer_type = fieldInfo->type;
-         f.type = qDecodeMYSQLType(fieldInfo->type, fieldInfo->flags);
-         if (qIsBlob(fieldInfo->type)) {
-             // the size of a blob-field is available as soon as we call
-             // mysql_stmt_store_result()
-             // after mysql_stmt_exec() in QMYSQLResult::exec()
--            fieldInfo->length = 0;
-+            bind->buffer_length = f.bufLength = 0;
-             hasBlobs = true;
-         } else if (qIsInteger(f.type)) {
--            fieldInfo->length = 8;
-+            bind->buffer_length = f.bufLength = 8;
-         } else {
--            fieldInfo->type = MYSQL_TYPE_STRING;
-+            bind->buffer_type = MYSQL_TYPE_STRING;
-         }
--        bind = &inBinds[i];
--        field = new char[fieldInfo->length + 1];
--        memset(field, 0, fieldInfo->length + 1);
- 
--        bind->buffer_type = fieldInfo->type;
--        bind->buffer = field;
--        bind->buffer_length = f.bufLength = fieldInfo->length + 1;
-         bind->is_null = &f.nullIndicator;
-         bind->length = &f.bufLength;
-         bind->is_unsigned = fieldInfo->flags & UNSIGNED_FLAG ? 1 : 0;
--        f.outField=field;
-+
-+        char *field = new char[bind->buffer_length + 1]{};
-+        bind->buffer = f.outField = field;
- 
-         ++i;
-     }
diff --git a/debian/patches/openssl_set_options.diff b/debian/patches/openssl_set_options.diff
new file mode 100644
index 00000000..62947914
--- /dev/null
+++ b/debian/patches/openssl_set_options.diff
@@ -0,0 +1,79 @@
+Description: update function argument of SSL_CTX_set_options
+ openssl3 uses uint64_t for the options argument in SSL_CTX_set_options,
+ older ones used long.
+ sizeof(long) is not the same on any platform as sizeof(uint64_t)
+Origin: upstream, https://code.qt.io/cgit/qt/qtbase.git/commit/?id=e995bfc0ea783c15
+ Backported for 5.15 by the patch author, Michael Saxl.
+Last-Update: 2022-08-07
+
+--- a/src/network/ssl/qsslcontext_openssl.cpp
++++ b/src/network/ssl/qsslcontext_openssl.cpp
+@@ -455,7 +455,7 @@ init_context:
+     }
+ 
+     // Enable bug workarounds.
+-    long options = QSslSocketBackendPrivate::setupOpenSslOptions(configuration.protocol(), configuration.d->sslOptions);
++    qssloptions options = QSslSocketBackendPrivate::setupOpenSslOptions(configuration.protocol(), configuration.d->sslOptions);
+     q_SSL_CTX_set_options(sslContext->ctx, options);
+ 
+     // Tell OpenSSL to release memory early
+--- a/src/network/ssl/qsslsocket_openssl.cpp
++++ b/src/network/ssl/qsslsocket_openssl.cpp
+@@ -550,9 +550,9 @@ static void q_loadCiphersForConnection(S
+ // Defined in qsslsocket.cpp
+ void q_setDefaultDtlsCiphers(const QList<QSslCipher> &ciphers);
+ 
+-long QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SslProtocol protocol, QSsl::SslOptions sslOptions)
++qssloptions QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SslProtocol protocol, QSsl::SslOptions sslOptions)
+ {
+-    long options;
++    qssloptions options;
+     if (protocol == QSsl::TlsV1SslV3)
+         options = SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3;
+     else if (protocol == QSsl::SecureProtocols)
+--- a/src/network/ssl/qsslsocket_openssl_p.h
++++ b/src/network/ssl/qsslsocket_openssl_p.h
+@@ -107,6 +107,12 @@
+ 
+ QT_BEGIN_NAMESPACE
+ 
++#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3
++typedef uint64_t qssloptions;
++#else
++typedef unsigned long qssloptions;
++#endif
++
+ struct QSslErrorEntry {
+     int code;
+     int depth;
+@@ -171,7 +177,7 @@ public:
+     QVector<QSslError> ocspErrors;
+     QByteArray ocspResponseDer;
+ 
+-    Q_AUTOTEST_EXPORT static long setupOpenSslOptions(QSsl::SslProtocol protocol, QSsl::SslOptions sslOptions);
++    Q_AUTOTEST_EXPORT static qssloptions setupOpenSslOptions(QSsl::SslProtocol protocol, QSsl::SslOptions sslOptions);
+     static QSslCipher QSslCipher_from_SSL_CIPHER(const SSL_CIPHER *cipher);
+     static QList<QSslCertificate> STACKOFX509_to_QSslCertificates(STACK_OF(X509) *x509);
+     static QList<QSslError> verify(const QList<QSslCertificate> &certificateChain, const QString &hostName);
+--- a/src/network/ssl/qsslsocket_openssl_symbols.cpp
++++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp
+@@ -157,7 +157,7 @@ DEFINEFUNC2(void, OPENSSL_sk_push, OPENS
+ DEFINEFUNC(void, OPENSSL_sk_free, OPENSSL_STACK *a, a, return, DUMMYARG)
+ DEFINEFUNC2(void *, OPENSSL_sk_value, OPENSSL_STACK *a, a, int b, b, return nullptr, return)
+ DEFINEFUNC(int, SSL_session_reused, SSL *a, a, return 0, return)
+-DEFINEFUNC2(unsigned long, SSL_CTX_set_options, SSL_CTX *ctx, ctx, unsigned long op, op, return 0, return)
++DEFINEFUNC2(qssloptions, SSL_CTX_set_options, SSL_CTX *ctx, ctx, qssloptions op, op, return 0, return)
+ DEFINEFUNC(int, SSL_CTX_get_security_level, const SSL_CTX *ctx, ctx, return -1, return)
+ DEFINEFUNC2(void, SSL_CTX_set_security_level, SSL_CTX *ctx, ctx, int level, level, return, return)
+ #ifdef TLS1_3_VERSION
+--- a/src/network/ssl/qsslsocket_openssl_symbols_p.h
++++ b/src/network/ssl/qsslsocket_openssl_symbols_p.h
+@@ -245,7 +245,7 @@ Q_AUTOTEST_EXPORT void q_OPENSSL_sk_push
+ Q_AUTOTEST_EXPORT void q_OPENSSL_sk_free(OPENSSL_STACK *a);
+ Q_AUTOTEST_EXPORT void * q_OPENSSL_sk_value(OPENSSL_STACK *a, int b);
+ int q_SSL_session_reused(SSL *a);
+-unsigned long q_SSL_CTX_set_options(SSL_CTX *ctx, unsigned long op);
++qssloptions q_SSL_CTX_set_options(SSL_CTX *ctx, qssloptions op);
+ int q_OPENSSL_init_ssl(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings);
+ size_t q_SSL_get_client_random(SSL *a, unsigned char *out, size_t outlen);
+ size_t q_SSL_SESSION_get_master_key(const SSL_SESSION *session, unsigned char *out, size_t outlen);
diff --git a/debian/patches/qmenu_set_transient_parent.diff b/debian/patches/qmenu_set_transient_parent.diff
new file mode 100644
index 00000000..a2afbb28
--- /dev/null
+++ b/debian/patches/qmenu_set_transient_parent.diff
@@ -0,0 +1,60 @@
+Description: widgets: setTransientParent() when a QMenu is a window
+ On some platforms, such as X11 and Wayland with some compositors,
+ QMenu could be a popup window, which should be set a transient parent
+ to get relative position, which is requested by Wayland.
+ .
+ Added transientParentWindow() for QMenuPrivate like QDialogPrivate.
+Origin: upstream, https://code.qt.io/cgit/qt/qtbase.git/commit/?id=493a85a9e4688744
+Last-Update: 2022-10-16
+
+--- a/src/widgets/widgets/qmenu.cpp
++++ b/src/widgets/widgets/qmenu.cpp
+@@ -624,6 +624,29 @@ void QMenuPrivate::hideMenu(QMenu *menu)
+     menu->d_func()->causedPopup.widget = nullptr;
+ }
+ 
++QWindow *QMenuPrivate::transientParentWindow() const
++{
++    Q_Q(const QMenu);
++    if (const QWidget *parent = q->nativeParentWidget()) {
++        if (parent->windowHandle())
++            return parent->windowHandle();
++    }
++
++    if (const QWindow *w = q->windowHandle()) {
++        if (w->transientParent())
++            return w->transientParent();
++    }
++
++    if (causedPopup.widget) {
++        if (const QWidget *w = causedPopup.widget.data()) {
++            if (const QWidget *ww = w->window())
++                return ww->windowHandle();
++        }
++    }
++
++    return nullptr;
++}
++
+ void QMenuPrivate::popupAction(QAction *action, int delay, bool activateFirst)
+ {
+     Q_Q(QMenu);
+@@ -3060,6 +3083,8 @@ QMenu::event(QEvent *e)
+         d->sloppyState.reset();
+         if (d->currentAction)
+             d->popupAction(d->currentAction, 0, false);
++        if (isWindow() && window() && window()->windowHandle() && !window()->windowHandle()->transientParent())
++            window()->windowHandle()->setTransientParent(d->transientParentWindow());
+         break;
+ #ifndef QT_NO_TOOLTIP
+     case QEvent::ToolTip:
+--- a/src/widgets/widgets/qmenu_p.h
++++ b/src/widgets/widgets/qmenu_p.h
+@@ -440,6 +440,7 @@ public:
+     QMenuCaused causedPopup;
+     void hideUpToMenuBar();
+     void hideMenu(QMenu *menu);
++    QWindow *transientParentWindow() const;
+ 
+     //index mappings
+     inline QAction *actionAt(int i) const { return q_func()->actions().at(i); }
diff --git a/debian/patches/qshapedpixmapwindow_no_tooltip.diff b/debian/patches/qshapedpixmapwindow_no_tooltip.diff
new file mode 100644
index 00000000..7e4dabfb
--- /dev/null
+++ b/debian/patches/qshapedpixmapwindow_no_tooltip.diff
@@ -0,0 +1,25 @@
+Description: do not set Qt::ToolTip flag for QShapedPixmapWindow
+ This hint is not really needed in the first place and only causes
+ problems in some environments.
+ .
+ For example in KDE, the compositor animates changes in position and size
+ for all ToolTip windows. However, this is not wanted here because we use
+ this window as a thumbnail for a drag-and-drop operation.
+ Before this patch the dragged element would lag significantly behind the
+ cursor. Now it works as expected, i.e. the dragged element follows the
+ cursor immediately.
+Origin: upstream, https://code.qt.io/cgit/qt/qtbase.git/commit/?id=180b496b537089b8
+Bug: https://bugreports.qt.io/browse/QTBUG-98048
+Last-Update: 2023-05-20
+
+--- a/src/gui/kernel/qshapedpixmapdndwindow.cpp
++++ b/src/gui/kernel/qshapedpixmapdndwindow.cpp
+@@ -56,7 +56,7 @@ QShapedPixmapWindow::QShapedPixmapWindow
+     QSurfaceFormat format;
+     format.setAlphaBufferSize(8);
+     setFormat(format);
+-    setFlags(Qt::ToolTip | Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint
++    setFlags(Qt::FramelessWindowHint | Qt::BypassWindowManagerHint
+              | Qt::WindowTransparentForInput | Qt::WindowDoesNotAcceptFocus);
+ }
+ 
diff --git a/debian/patches/qxcbwindow_set_geometry.diff b/debian/patches/qxcbwindow_set_geometry.diff
new file mode 100644
index 00000000..76ac96a9
--- /dev/null
+++ b/debian/patches/qxcbwindow_set_geometry.diff
@@ -0,0 +1,44 @@
+Description: set geometry property in QXcbWindow after checking minimum size
+ QXcbWindow::create() bound the window's size to windowMinimumSize(),
+ after its size had been inherited from parent().
+ QPlatformWindow::setGeometry() was called before that sanity check.
+ .
+ When a fullscreen window is re-mapped from a deactivated screen to the
+ remaining screen, the call to QPlatformWindow::setGeometry() assigns
+ an invalid QRect to QPlatformWindowPrivate::rect
+ The negative int values x2 and/or y2 cause
+ QXcbBackingStoreImage::flushPixmap to address unmapped memory and
+ crash.
+ .
+ This patch moves the call to QPlatformWindow::setGeometry() from
+ before to after bounding to a minimum value. That assures a valid
+ rectangle to be assigned in all cases.
+Origin: upstream, https://code.qt.io/cgit/qt/qtbase.git/commit/?id=6a3627b6c5aa5109
+Last-Update: 2023-01-04
+
+--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
++++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
+@@ -299,11 +299,6 @@ void QXcbWindow::create()
+         return;
+     }
+ 
+-    QPlatformWindow::setGeometry(rect);
+-
+-    if (platformScreen != currentScreen)
+-        QWindowSystemInterface::handleWindowScreenChanged(window(), platformScreen->QPlatformScreen::screen());
+-
+     const QSize minimumSize = windowMinimumSize();
+     if (rect.width() > 0 || rect.height() > 0) {
+         rect.setWidth(qBound(1, rect.width(), XCOORD_MAX));
+@@ -315,6 +310,11 @@ void QXcbWindow::create()
+         rect.setHeight(QHighDpi::toNativePixels(int(defaultWindowHeight), platformScreen->QPlatformScreen::screen()));
+     }
+ 
++    QPlatformWindow::setGeometry(rect);
++
++    if (platformScreen != currentScreen)
++        QWindowSystemInterface::handleWindowScreenChanged(window(), platformScreen->QPlatformScreen::screen());
++
+     xcb_window_t xcb_parent_id = platformScreen->root();
+     if (parent()) {
+         xcb_parent_id = static_cast<QXcbWindow *>(parent())->xcb_window();
diff --git a/debian/patches/remove_limit_on_number_of_streams.diff b/debian/patches/remove_limit_on_number_of_streams.diff
deleted file mode 100644
index 0d71c56a..00000000
--- a/debian/patches/remove_limit_on_number_of_streams.diff
+++ /dev/null
@@ -1,50 +0,0 @@
-Description: H2: remove a rather useless limit on the number of streams
- SETTINGS for max concurrect number of streams is 'one direction' - this
- is how our peer conveys the possible number of streams _we_ can open,
- not _them_. If they choose to have it unlimited - let it be so.
- .
- It's possible to send 0 as maximum number, also, it's possible to
- reduce the maximum compared to initial at some point - then I have
- to avoid integer overflows.
-Origin: upstream, https://code.qt.io/cgit/qt/qtbase.git/commit/?id=46940ca73791e87e
-Last-Update: 2022-06-20
-
---- a/src/network/access/http2/http2protocol_p.h
-+++ b/src/network/access/http2/http2protocol_p.h
-@@ -133,9 +133,6 @@ enum Http2PredefinedParameters
-     maxPayloadSize = (1 << 24) - 1, // HTTP/2 6.5.2
- 
-     defaultSessionWindowSize = 65535, // HTTP/2 6.5.2
--    // Using 1000 (rather arbitrarily), just to
--    // impose *some* upper limit:
--    maxPeerConcurrentStreams  = 1000,
-     maxConcurrentStreams = 100 // HTTP/2, 6.5.2
- };
- 
---- a/src/network/access/qhttp2protocolhandler.cpp
-+++ b/src/network/access/qhttp2protocolhandler.cpp
-@@ -393,7 +393,8 @@ bool QHttp2ProtocolHandler::sendRequest(
-         initReplyFromPushPromise(message, key);
-     }
- 
--    const auto streamsToUse = std::min<quint32>(maxConcurrentStreams - activeStreams.size(),
-+    const auto streamsToUse = std::min<quint32>(maxConcurrentStreams > activeStreams.size()
-+                                                ? maxConcurrentStreams - activeStreams.size() : 0,
-                                                 requests.size());
-     auto it = requests.begin();
-     for (quint32 i = 0; i < streamsToUse; ++i) {
-@@ -1084,13 +1085,8 @@ bool QHttp2ProtocolHandler::acceptSettin
-         QMetaObject::invokeMethod(this, "resumeSuspendedStreams", Qt::QueuedConnection);
-     }
- 
--    if (identifier == Settings::MAX_CONCURRENT_STREAMS_ID) {
--        if (newValue > maxPeerConcurrentStreams) {
--            connectionError(PROTOCOL_ERROR, "SETTINGS invalid number of concurrent streams");
--            return false;
--        }
-+    if (identifier == Settings::MAX_CONCURRENT_STREAMS_ID)
-         maxConcurrentStreams = newValue;
--    }
- 
-     if (identifier == Settings::MAX_FRAME_SIZE_ID) {
-         if (newValue < Http2::minPayloadLimit || newValue > Http2::maxPayloadSize) {
diff --git a/debian/patches/revert_startBlocking_removal.diff b/debian/patches/revert_startBlocking_removal.diff
new file mode 100644
index 00000000..3537b759
--- /dev/null
+++ b/debian/patches/revert_startBlocking_removal.diff
@@ -0,0 +1,102 @@
+Description: revert "Remove the dead code for blocking methods from QtConcurrent"
+ It's a binary incompatible change.
+Origin: KDE, https://invent.kde.org/qt/qt/qtbase/-/commit/eeadc036d77b75be
+ Also submitted to upstream 5.15 branch according to
+ https://lists.qt-project.org/pipermail/development/2022-September/042951.html.
+Last-Update: 2022-09-10
+
+--- a/src/concurrent/qtconcurrentthreadengine.cpp
++++ b/src/concurrent/qtconcurrentthreadengine.cpp
+@@ -176,6 +176,39 @@ void ThreadEngineBase::startSingleThread
+     finish();
+ }
+ 
++void ThreadEngineBase::startBlocking()
++{
++    start();
++    barrier.acquire();
++    startThreads();
++
++    bool throttled = false;
++#ifndef QT_NO_EXCEPTIONS
++    try {
++#endif
++        while (threadFunction() == ThrottleThread) {
++            if (threadThrottleExit()) {
++                throttled = true;
++                break;
++            }
++        }
++#ifndef QT_NO_EXCEPTIONS
++    } catch (QException &e) {
++        handleException(e);
++    } catch (...) {
++        handleException(QUnhandledException());
++    }
++#endif
++
++    if (throttled == false) {
++        barrier.release();
++    }
++
++    barrier.wait();
++    finish();
++    exceptionStore.throwPossibleException();
++}
++
+ void ThreadEngineBase::startThread()
+ {
+     startThreadInternal();
+--- a/src/concurrent/qtconcurrentthreadengine.h
++++ b/src/concurrent/qtconcurrentthreadengine.h
+@@ -91,6 +91,7 @@ public:
+     ThreadEngineBase();
+     virtual ~ThreadEngineBase();
+     void startSingleThreaded();
++    void startBlocking();
+     void startThread();
+     bool isCanceled();
+     void waitForResume();
+@@ -144,6 +145,15 @@ public:
+     }
+ 
+     // Runs the user algorithm using multiple threads.
++    // This function blocks until the algorithm is finished,
++    // and then returns the result.
++    T *startBlocking()
++    {
++        ThreadEngineBase::startBlocking();
++        return result();
++    }
++
++    // Runs the user algorithm using multiple threads.
+     // Does not block, returns a future.
+     QFuture<T> startAsynchronously()
+     {
+@@ -223,6 +233,13 @@ class ThreadEngineStarter : public Threa
+ public:
+     ThreadEngineStarter(TypedThreadEngine *eng)
+         : Base(eng) { }
++
++    T startBlocking()
++    {
++        T t = *this->threadEngine->startBlocking();
++        delete this->threadEngine;
++        return t;
++    }
+ };
+ 
+ // Full template specialization where T is void.
+@@ -232,6 +249,12 @@ class ThreadEngineStarter<void> : public
+ public:
+     ThreadEngineStarter(ThreadEngine<void> *_threadEngine)
+         : ThreadEngineStarterBase<void>(_threadEngine) {}
++
++    void startBlocking()
++    {
++        this->threadEngine->startBlocking();
++        delete this->threadEngine;
++    }
+ };
+ 
+ //! [qtconcurrentthreadengine-1]
diff --git a/debian/patches/series b/debian/patches/series
index 095a51a2..d4981851 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,15 +1,25 @@
 # Backported from upstream.
 #mime_globs.diff
-#fix-misplacement-of-placeholder-text-in-QLineEdit.diff
-#fix-placement-of-placeholder-text-in-QLineEdits-with-action-icons.diff
-#full_width_selection_rtl.diff
-#fix_recursion_crash.diff
-#mysql_field_readonly.diff
-#CVE-2021-38593.diff
+#fusion_checkable_qpushbutton.diff
 #openssl3.diff
-#CVE-2022-25255.diff
-#moc_handle_include.diff
-#remove_limit_on_number_of_streams.diff
+#openssl_set_options.diff
+qmenu_set_transient_parent.diff
+gnome_wayland.diff
+#fix_alt_backtick.diff
+#image_deletion_order.diff
+#qxcbwindow_set_geometry.diff
+#CVE-2023-24607.diff
+#qshapedpixmapwindow_no_tooltip.diff
+#CVE-2023-32763.diff
+#CVE-2023-32762.diff
+#CVE-2023-33285.diff
+#CVE-2023-34410.diff
+sql_odbc_more_unicode_checks.diff
+sql_odbc_fix_unicode_check.diff
+a11y_root.diff
+dont_use_O_PATH.diff
+#fix_qdbusmacros_h.diff
+
 
 # Debian specific.
 gnukfreebsd.diff
diff --git a/debian/patches/sql_odbc_fix_unicode_check.diff b/debian/patches/sql_odbc_fix_unicode_check.diff
new file mode 100644
index 00000000..dd27b32e
--- /dev/null
+++ b/debian/patches/sql_odbc_fix_unicode_check.diff
@@ -0,0 +1,32 @@
+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
+
+--- a/src/plugins/sqldrivers/odbc/qsql_odbc.cpp
++++ b/src/plugins/sqldrivers/odbc/qsql_odbc.cpp
+@@ -125,7 +125,6 @@ inline static QVarLengthArray<SQLTCHAR>
+ {
+     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;
+ }
+ 
+@@ -2119,7 +2118,8 @@ void QODBCDriverPrivate::checkUnicode()
+         QLatin1String("select 'test' from dual"),
+     };
+     for (const auto &statement : statements) {
+-        r = SQLExecDirect(hStmt, toSQLTCHAR(statement).data(), SQL_NTS);
++        auto encoded = toSQLTCHAR(statement);
++        r = SQLExecDirect(hStmt, encoded.data(), SQLINTEGER(encoded.size()));
+         if (r == SQL_SUCCESS)
+             break;
+     }
diff --git a/debian/patches/sql_odbc_more_unicode_checks.diff b/debian/patches/sql_odbc_more_unicode_checks.diff
new file mode 100644
index 00000000..de7d2d9a
--- /dev/null
+++ b/debian/patches/sql_odbc_more_unicode_checks.diff
@@ -0,0 +1,35 @@
+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
+
+--- a/src/plugins/sqldrivers/odbc/qsql_odbc.cpp
++++ b/src/plugins/sqldrivers/odbc/qsql_odbc.cpp
+@@ -2111,7 +2111,18 @@ void QODBCDriverPrivate::checkUnicode()
+                                   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) {
diff --git a/debian/patches/xdg_filechooser_portal_send_window_id_in_hex.diff b/debian/patches/xdg_filechooser_portal_send_window_id_in_hex.diff
deleted file mode 100644
index 76abafe1..00000000
--- a/debian/patches/xdg_filechooser_portal_send_window_id_in_hex.diff
+++ /dev/null
@@ -1,18 +0,0 @@
-Description: FileChooser portal: send window id in hex
- We send window id in decimal, however, it is expected to be send in hex.
- This causes a mismatch and makes portal dialog to show in background.
-Origin: upstream, https://code.qt.io/cgit/qt/qtbase.git/commit/?id=acaabc9108dfe75530960cf8e3ec4f3602cd82e0
-Last-Update: 2021-11-04
-Index: qtbase-opensource-src/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp
-===================================================================
---- qtbase-opensource-src.orig/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp
-+++ qtbase-opensource-src/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp
-@@ -185,7 +185,7 @@ void QXdgDesktopPortalFileDialog::openPo
-                                                           QLatin1String("/org/freedesktop/portal/desktop"),
-                                                           QLatin1String("org.freedesktop.portal.FileChooser"),
-                                                           d->saveFile ? QLatin1String("SaveFile") : QLatin1String("OpenFile"));
--    QString parentWindowId = QLatin1String("x11:") + QString::number(d->winId);
-+    QString parentWindowId = QLatin1String("x11:") + QString::number(d->winId, 16);
- 
-     QVariantMap options;
-     if (!d->acceptLabel.isEmpty())


More information about the Neon-commits mailing list