Skip to content

Conversation

@varjolintu
Copy link
Member

Continues work from #10267, using #11003 as the base.

Fixes #7774.

Type of change

  • ✅ Refactor (significant modification to existing code)

@varjolintu varjolintu added pr: refactoring Pull request refactors code Qt labels Jan 12, 2025
@varjolintu varjolintu added this to the v2.8.0 milestone Jan 12, 2025
@varjolintu varjolintu mentioned this pull request Jan 12, 2025
7 tasks
@varjolintu varjolintu changed the title Qt6 ver2 WIP: Qt6 transition Jan 12, 2025
# TODO: Increase minimum to 2.19.1 and drop Argon2 package
find_package(Botan REQUIRED)
if(BOTAN_VERSION VERSION_GREATER_EQUAL "3.0.0")
set(WITH_BOTAN3 TRUE)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is still a reference to the old define in src/fdosecrets/objects/SessionCipher.cpp:#ifdef WITH_XC_BOTAN3

@Hasshu
Copy link

Hasshu commented Feb 16, 2025

Any chance of this making it into v2.7.10? Apparently, Qt 5 is pretty much unsupported at this point.

@varjolintu
Copy link
Member Author

Any chance of this making it into v2.7.10? Apparently, Qt 5 is pretty much unsupported at this point.

No. This needs more work.

@Hasshu
Copy link

Hasshu commented Feb 17, 2025

@varjolintu Gotcha. Keep up the good work!

@xgqt
Copy link

xgqt commented May 8, 2025

QT5 in Gentoo and other (GNU/)Linux distros will be gettting slowly removed. Please see also: https://bugs.gentoo.org/949231
Sadly, I do not have time to help with code for porting. Could help with testing though.
Thanks in advance and very sorry for the noise! :D

droidmonkey and others added 13 commits May 10, 2025 15:42
* Remove individual feature flags in favor of a single `KPXC_MINIMAL` flag that removes advanced features from the build. Basic features are no longer guarded by feature flags.
* Basic features: Auto-Type, Yubikey, KeeShare
* Advanced features include: Browser (and passkeys), SSH Agent, and Secret Service
* Networking, Documentation, and Update Checking remain as feature flags to accommodate various distro requirements.

This change also cleans up the main CMakeLists.txt by re-arranging some content and placing macros into a dedicated include file. The minimum CMake version was bumped to 3.16.0 to conform to our minimum Ubuntu support of Focal (20.04). This also allows us to default to C++20, we fall back to C++17 for Qt versions less than 5.15.0 due to lack of support.

Lastly this change removes the KEEPASSXC_BUILD_TYPE="PreRelease" which is never used. We only support "Snapshot" and "Release" now.
- Fix missing X11 library for linker
- Other Linux fixes

NOTE: FDOSECRETS CURRENTLY CRASHES WHEN ATTEMPTING TO BE USED
* Also reduce minimum Qt version to 6.4.2 to align with Ubuntu 24.04
* Remove Qt6 from vcpkg, prefer use of installed libraries using Qt6_DIR CMake variable.
* Update baseline to latest and remove version minimums since they are not actually minimums but just "something newer than the baseline". See https://devblogs.microsoft.com/cppblog/take-control-of-your-vcpkg-dependencies-with-versioning-support/#how-versioning-works-in-vcpkg
* Revert back to using char instead of wchar_t for PCSC function calls. Linux and macOS don't support widechar calls yet
* Fix signal/slot break in Password Generator
* Add missing POST_BUILD parameters to cmake custom command calls
#ifdef WITH_XC_X11
auto keycode = XKeysymToKeycode(dpy, qcharToNativeKeyCode(key));
#ifdef WITH_X11
auto keycode = XKeysymToKeycode(dpy, qcharToNativeKeyCode(QChar(key)));
Copy link

@ghost ghost Jul 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to make this change:

-    auto keycode = XKeysymToKeycode(dpy, qcharToNativeKeyCode(QChar(key)));
+    auto keycode = XKeysymToKeycode(dpy, qcharToNativeKeyCode(QChar(static_cast<uint>(key))));

to get it to build on my setup.

Copy link

@0xIO32 0xIO32 Jul 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this pr already usable?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I this pr already usable?

It builds, runs and can open my KDBX database. I haven't tested further. There might be a showstopping bug somewhere that @varjolintu isn't happy with since he mentioned it "needs more work"... I can't tell.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Everything just needs to be checked. It's possible that we merge this when possible and the do more fixes later when possible problems are found.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't make sense to force a Qt::Key to QChar. We should use qtToNativeKeyCode directly.

Suggested change
auto keycode = XKeysymToKeycode(dpy, qcharToNativeKeyCode(QChar(key)));
auto keycode = XKeysymToKeycode(dpy, qtToNativeKeyCode(key));

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Aetf This is on my fix list too. I'll update this branch this week when I have the time.

@ghost
Copy link

ghost commented Jul 26, 2025

Stuff under /src/fdosecrets seems to be completely broken. I'm not familiar with the codebase but I assume this is a custom DBus layer. @varjolintu I recommend looking at the testguifdosecrets GUI tests, they're failing because the DBus layer broke.
@Aetf Since you wrote the original implementation, could you help out?

@Aetf
Copy link
Contributor

Aetf commented Jul 27, 2025

I may be able to take a look this weekend. Too sad that I couldn't spend more time on this.

What is breaking about fdosecrets? It has some custom code to make handling fdosecrets secret service related dbus objects easier. I don't remember anything too out of ordinary from top of my head that would break due to Qt6 though...

@ghost
Copy link

ghost commented Jul 27, 2025

I may be able to take a look this weekend. Too sad that I couldn't spend more time on this.

What is breaking about fdosecrets? It has some custom code to make handling fdosecrets secret service related dbus objects easier. I don't remember anything too out of ordinary from top of my head that would break due to Qt6 though...

For one, DBusMgr::deliverMethod is failing for (probably) all the tests:

QWARN  : TestGuiFdoSecrets::testServiceEnable() Internal error: Failed to convert message output to type 65540
QDEBUG : TestGuiFdoSecrets::testServiceEnable() Failed to deliver method QDBusMessage(type=MethodCall, service=":1.0", path="/org/freedesktop/secrets", interface="org.freedesktop.Secret.Service", member="ReadAlias", signature="s", contents=("default") )

The type ID 65540 seems to be QDBusObjectPath.

bool DBusMgr::deliverMethod(...)
{
    ...

    // output args need to be converted before they can be directly sent out:
    for (int i = 0; i != outputArgs.size(); ++i) {
        auto& outputArg = outputArgs[i];
        if (!outputArg.convert(method.outputTargetTypes.at(i))) {
            qWarning() << "Internal error: Failed to convert message output to type"
                       << method.outputTargetTypes.at(i);
            return false;
        }
    }

    ...

The qWarning() ... line is being reached and outputArg.metaType() isn't even a different type from method.outputTargetTypes.at(i). If I skip this check, it crashes.

// Under CollectionProxy of FdoSecretsProxy.h
inline PropertyReply<bool> locked() const
{
    IMPL_GET_PROPERTY(Locked); // crashes here, specifically at the QDBusConnection::call call, inside of which stack traces aren't available
}

@ghost
Copy link

ghost commented Jul 27, 2025

image I don't think this does what you think it does?

@ghost
Copy link

ghost commented Jul 27, 2025

@Aetf Turns out the QVariant() constructor calls are not supposed to take type IDs anymore in Qt 6.

https://doc.qt.io/qt-6/qvariant-obsolete.html

Same with the convert calls on output args after calling qt_metacall - they're supposed to take QMetaType now.

What I've done so far:

diff --git a/src/fdosecrets/dbus/DBusDispatch.cpp b/src/fdosecrets/dbus/DBusDispatch.cpp
index eee63bdb..0165c62d 100644
--- a/src/fdosecrets/dbus/DBusDispatch.cpp
+++ b/src/fdosecrets/dbus/DBusDispatch.cpp
@@ -20,7 +20,6 @@
 
 #include <QDBusMetaType>
 #include <QThread>
-#include <QtDBus>
 
 namespace FdoSecrets
 {
@@ -32,29 +31,37 @@ namespace FdoSecrets
         return camel.at(0).toUpper() + camel.mid(1);
     }
 
-    bool prepareInputParams(const QVector<int>& inputTypes,
+    bool prepareInputParams(const DBusClientPtr& client,
+                            const QVector<int>& inputTypes,
+                            bool needsCallingClient,
                             const QVariantList& args,
+                            DBusResult& ret,
                             QVarLengthArray<void*, 10>& params,
                             QVariantList& auxParams)
     {
-        // prepare params
+        // reserve to avoid reallocation
+        auxParams.reserve(inputTypes.size() + (needsCallingClient ? 1 : 0));
+
+        // fill auxParams
+        if (needsCallingClient) {
+            auxParams.append(QVariant::fromValue(client));
+        }
+
         for (int count = 0; count != inputTypes.size(); ++count) {
             const auto& id = inputTypes.at(count);
             const auto& arg = args.at(count);
 
             if (arg.userType() == id) {
-                // shortcut for no conversion
-                params.append(const_cast<void*>(arg.constData()));
+                // skip conversion
+                auxParams.append(arg);
                 continue;
             }
 
-            // we need at least one conversion, allocate a slot in auxParams
-            auxParams.append(QVariant(id));
-            auto& out = auxParams.last();
-            // first handle QDBusArgument to wire types
+            QVariant out{QMetaType(id)};
+
             if (arg.userType() == qMetaTypeId<QDBusArgument>()) {
                 QMetaType wireId(typeToWireType(id).dbusTypeId);
-                out = QVariant(wireId, nullptr);
+                out = QVariant(QMetaType(wireId), nullptr);
 
                 const auto& in = arg.value<QDBusArgument>();
                 if (!QDBusMetaType::demarshall(in, wireId, out.data())) {
@@ -63,18 +70,24 @@ namespace FdoSecrets
                     return false;
                 }
             } else {
-                // make a copy to store the converted value
                 out = arg;
             }
-            // other conversions are handled here
-            if (!out.convert(id)) {
-                qDebug() << "Internal error: failed conversion from" << arg << "to type" << QMetaType::typeName(id)
-                         << id;
+
+            if (!out.convert(QMetaType(id))) {
+                qDebug() << "Internal error: failed conversion from" << arg << "to type"
+                         << QMetaType::typeName(id) << id;
                 return false;
             }
-            // good to go
-            params.append(const_cast<void*>(out.constData()));
+
+            auxParams.append(std::move(out));
+        }
+
+        // fill params from auxParams
+        params.append(&ret); // first slot for return value
+        for (const QVariant& var : auxParams) {
+            params.append(const_cast<void*>(var.constData()));
         }
+
         return true;
     }
 
@@ -341,16 +354,8 @@ namespace FdoSecrets
         QVarLengthArray<void*, 10> params;
         QVariantList auxParams;
 
-        // the first one is for return type
-        params.append(&ret);
-
-        if (method.needsCallingClient) {
-            auxParams.append(QVariant::fromValue(client));
-            params.append(const_cast<void*>(auxParams.last().constData()));
-        }
-
         // prepare input
-        if (!prepareInputParams(method.inputTypes, args, params, auxParams)) {
+        if (!prepareInputParams(client, method.inputTypes, method.needsCallingClient, args, ret, params, auxParams)) {
             qDebug() << "Failed to prepare input params";
             return false;
         }
@@ -358,7 +363,7 @@ namespace FdoSecrets
         // prepare output args
         outputArgs.reserve(outputArgs.size() + method.outputTypes.size());
         for (const auto& outputType : asConst(method.outputTypes)) {
-            outputArgs.append(QVariant(outputType));
+            outputArgs.append(QVariant(QMetaType(outputType)));
             params.append(const_cast<void*>(outputArgs.last().constData()));
         }
 
@@ -378,10 +383,17 @@ namespace FdoSecrets
         // output args need to be converted before they can be directly sent out:
         for (int i = 0; i != outputArgs.size(); ++i) {
             auto& outputArg = outputArgs[i];
-            if (!outputArg.convert(method.outputTargetTypes.at(i))) {
-                qWarning() << "Internal error: Failed to convert message output to type"
-                           << method.outputTargetTypes.at(i);
+
+            QMetaType fromType = outputArg.metaType();
+            QMetaType toType = QMetaType(method.outputTargetTypes.at(i));
+
+            QVariant result(toType); // default-construct target type
+            if (!QMetaType::convert(fromType, outputArg.constData(), toType, result.data())) {
+                qWarning() << "Internal error: Failed to convert message output from type"
+                           << fromType.name() << "to type" << toType.name();
                 return false;
+            } else {
+                outputArg = result;
             }
         }

This should get a handful of tests to pass.

Some test cases under testguifdosecrets are still failing/crashing, I'll try to find out what went wrong with those. For now @varjolintu if you can, please apply the patch above to DBusDispatch.cpp.

@ghost
Copy link

ghost commented Jul 28, 2025

TestGuiFdoSecrets::testCollectionDeleteConcurrent currently crashes because DatabaseWidget::performSave calls QApplication::processEvents which in turns calls DatabaseWidget::performSave again.

@Aetf
Copy link
Contributor

Aetf commented Jul 28, 2025

Working on the code now. Also need the following patch to get gui tests to compile, due to QScopedPointer requires no inline constructor, destructor and assignment operators. https://doc.qt.io/qt-6/qscopedpointer.html#forward-declared-pointers

diff --git a/tests/gui/TestGuiFdoSecrets.cpp b/tests/gui/TestGuiFdoSecrets.cpp
index fc7e218e..88d20db5 100644
--- a/tests/gui/TestGuiFdoSecrets.cpp
+++ b/tests/gui/TestGuiFdoSecrets.cpp
@@ -131,6 +131,7 @@ char* toString(const QDBusObjectPath& path)
     return QTest::toString("ObjectPath(" + path.path() + ")");
 }
 
+TestGuiFdoSecrets::TestGuiFdoSecrets() = default;
 TestGuiFdoSecrets::~TestGuiFdoSecrets() = default;
 
 void TestGuiFdoSecrets::initTestCase()
diff --git a/tests/gui/TestGuiFdoSecrets.h b/tests/gui/TestGuiFdoSecrets.h
index 1624eed4..c6809f38 100644
--- a/tests/gui/TestGuiFdoSecrets.h
+++ b/tests/gui/TestGuiFdoSecrets.h
@@ -55,6 +55,7 @@ class TestGuiFdoSecrets : public QObject
     Q_OBJECT
 
 public:
+    explicit TestGuiFdoSecrets();
     ~TestGuiFdoSecrets() override;
 
 private slots:
@@ -145,6 +146,8 @@ private:
     }
 
 private:
+    Q_DISABLE_COPY(TestGuiFdoSecrets)
+
     QScopedPointer<MainWindow> m_mainWindow;
     QPointer<DatabaseTabWidget> m_tabWidget;
     QPointer<DatabaseWidget> m_dbWidget;

@varjolintu
Copy link
Member Author

Thank you :) This makes our job a little bit easier.

@Aetf
Copy link
Contributor

Aetf commented Jul 28, 2025

@mutativesystems Thanks for spotting the deprecated QVariant methods. That's super hard to debug! However I think your patch for DBusDispatch.cpp only works because you effectively removed the IsNull check in QVariant::convert. Your impl is exactly the same as Qt's internal impl except that check: https://codebrowser.dev/qt6/qtbase/src/corelib/kernel/qvariant.cpp.html#2137

Therefore after the patch even if the code can progress, there are multiple other errors.

The real issue is outputArgs are all null somehow after qt_metacall. Here's the log output after I added more debug logging:

QWARN  : TestGuiFdoSecrets::testServiceEnable() readAlias "default"
QWARN  : TestGuiFdoSecrets::testServiceEnable() readAlias got collection FdoSecrets::Collection(0x7ccbcaf53620)
QWARN  : TestGuiFdoSecrets::testServiceEnable() outputArg is null true
QWARN  : TestGuiFdoSecrets::testServiceEnable() outputArg is valid true
QWARN  : TestGuiFdoSecrets::testServiceEnable() outputArg type is QVariant(FdoSecrets::Collection*, 0x7ccbcaf53620) usertype: 65592 type id: 65592
QWARN  : TestGuiFdoSecrets::testServiceEnable() outputTargetTypes.at(i) i: 0 value: 65540 is QMetaType(QDBusObjectPath)
QWARN  : TestGuiFdoSecrets::testServiceEnable() Internal error: Failed to convert message output QVariant(QDBusObjectPath, QDBusObjectPath(""))  to type QMetaType(QDBusObjectPath)
FAIL!  : TestGuiFdoSecrets::testServiceEnable() 'rep.isValid()' returned FALSE. (org.qtproject.QtDBus.Error.InternalError)

I still don't get why outputArg is null... Too late for me so I have to stop here. But I feel we are close if we can manage to fix this.

@ghost
Copy link

ghost commented Jul 28, 2025

@mutativesystems Thanks for spotting the deprecated QVariant methods. That's super hard to debug! However I think your patch for DBusDispatch.cpp only works because you effectively removed the IsNull check in QVariant::convert. Your impl is exactly the same as Qt's internal impl except that check: https://codebrowser.dev/qt6/qtbase/src/corelib/kernel/qvariant.cpp.html#2137

Therefore after the patch even if the code can progress, there are multiple other errors.

That test case actually passes just fine for me. I edited my comment several times, so make sure you have the new prepareInputParams fix which previously mutilated the pointers in the params QList in deliverMethod.

Edit 1: I take it back, you're right. I'll debug this some more.

Edit 2: this can be fixed like so:

diff --git a/src/fdosecrets/dbus/DBusDispatch.cpp b/src/fdosecrets/dbus/DBusDispatch.cpp
index 0165c62d..6c5f1abd 100644
--- a/src/fdosecrets/dbus/DBusDispatch.cpp
+++ b/src/fdosecrets/dbus/DBusDispatch.cpp
@@ -363,7 +363,7 @@ namespace FdoSecrets
         // prepare output args
         outputArgs.reserve(outputArgs.size() + method.outputTypes.size());
         for (const auto& outputType : asConst(method.outputTypes)) {
-            outputArgs.append(QVariant(QMetaType(outputType)));
+            outputArgs.append(QVariant(QMetaType(outputType), QMetaType(outputType).create()));
             params.append(const_cast<void*>(outputArgs.last().constData()));
         }
 
@@ -383,17 +383,12 @@ namespace FdoSecrets
         // output args need to be converted before they can be directly sent out:
         for (int i = 0; i != outputArgs.size(); ++i) {
             auto& outputArg = outputArgs[i];
+            auto toType = QMetaType(method.outputTargetTypes.at(i));
 
-            QMetaType fromType = outputArg.metaType();
-            QMetaType toType = QMetaType(method.outputTargetTypes.at(i));
-
-            QVariant result(toType); // default-construct target type
-            if (!QMetaType::convert(fromType, outputArg.constData(), toType, result.data())) {
+            if (!outputArg.convert(toType)) {
                 qWarning() << "Internal error: Failed to convert message output from type"
-                           << fromType.name() << "to type" << toType.name();
+                           << outputArg.metaType().name() << "to type" << toType.name();
                 return false;
-            } else {
-                outputArg = result;
             }
         }

Basically to make a QVariant containing a default value instead of a null, we have to use QVariant(QMetaType(outputType), QMetaType(outputType).create()) instead of just QVariant(QMetaType(outputType))

@ghost
Copy link

ghost commented Jul 28, 2025

TestGuiFdoSecrets::testCollectionDeleteConcurrent currently crashes because DatabaseWidget::performSave calls QApplication::processEvents which in turns calls DatabaseWidget::performSave again.

For this I'll wait for someone else to figure this out - I'm not familiar with Qt or KPXC's codebase; for now I'm just self-compiling and using it with fdosecrets disabled in CMake.

@varjolintu
Copy link
Member Author

varjolintu commented Aug 4, 2025

TestGuiFdoSecrets::testCollectionDeleteConcurrent currently crashes because DatabaseWidget::performSave calls QApplication::processEvents which in turns calls DatabaseWidget::performSave again.

For this I'll wait for someone else to figure this out - I'm not familiar with Qt or KPXC's codebase; for now I'm just self-compiling and using it with fdosecrets disabled in CMake.

I took a quick look, but couldn't find the reason yet. I'm pretty sure it's related to the new code changes in DBusDispatch.cpp, and not the events or performSave() itself.

EDIT: If I revert the line outputArgs.append(QVariant(QMetaType(outputType), QMetaType(outputType).create())); back to the version without .create(), then the tests just fail but won't crash.

@ghost
Copy link

ghost commented Aug 4, 2025

EDIT: If I revert the line outputArgs.append(QVariant(QMetaType(outputType), QMetaType(outputType).create())); back to the version without .create(), then the tests just fail but won't crash.

@varjolintu You probably don't want to do that. Qt6's QVariant has a separate internal is-null flag that won't go away just by setting the internal pointer to something else. If you revert the patch, the QVariant conversions will fail again and the tests will obviously fail. @Aetf correctly pointed it out earlier.

@Aetf
Copy link
Contributor

Aetf commented Aug 5, 2025

outputArgs.append(QVariant(QMetaType(outputType), QMetaType(outputType).create()));

For this, the expectation is that the qt_metacall below after preparing the outputs should have set the output QVariants to something not null.

Simply initializing the output QVariants to a default value may make the convert pass, but I'm afraid that the actual outputs from the method call aren't passed out.

IMHO the problem is probably because qt_metacall changes its semantic or signature. We'll need to take a look at how qt_metacall are generated now in Qt6. (I can do this later this week.) Too bad Qt6 still doesn't have a proper API to dynamically invoke a QObject method with QVariant arguments.

@varjolintu
Copy link
Member Author

EDIT: If I revert the line outputArgs.append(QVariant(QMetaType(outputType), QMetaType(outputType).create())); back to the version without .create(), then the tests just fail but won't crash.

@varjolintu You probably don't want to do that. Qt6's QVariant has a separate internal is-null flag that won't go away just by setting the internal pointer to something else. If you revert the patch, the QVariant conversions will fail again and the tests will obviously fail. @Aetf correctly pointed it out earlier.

I know. Just tried to narrow the possible cause for the crash.

@the-nic
Copy link

the-nic commented Nov 20, 2025

I've tried to compile the current state with qt 6.10 on arch. My changes can be found in https://github.com/the-nic/keepassxc/tree/qt6_ver2 It seems to work fine, mostly. The tests in TestGuiFdoSecrets crash still, unsurprisingly.

Also, with ASan enabled, I get a lot of Leak issues reported, and I had to set ASAN_OPTIONS=alloc_dealloc_mismatch=0:

=================================================================
==163631==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 184 byte(s) in 1 object(s) allocated from:
    #0 0x7c79346f25dd in calloc /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_malloc_linux.cpp:74
    #1 0x7c7930d71ac3  (/usr/lib/libdbus-1.so.3+0x24ac3) (BuildId: 65f44f39f68b8f63de82c45fc6108bfc66c0247a)
    #2 0x7c7930d72e56 in dbus_message_new_error (/usr/lib/libdbus-1.so.3+0x25e56) (BuildId: 65f44f39f68b8f63de82c45fc6108bfc66c0247a)
    #3 0x7c7930d64940 in dbus_connection_send_with_reply (/usr/lib/libdbus-1.so.3+0x17940) (BuildId: 65f44f39f68b8f63de82c45fc6108bfc66c0247a)
    #4 0x7c7930d64d2b in dbus_connection_send_with_reply_and_block (/usr/lib/libdbus-1.so.3+0x17d2b) (BuildId: 65f44f39f68b8f63de82c45fc6108bfc66c0247a)
    #5 0x7c7930d64fed in dbus_bus_register (/usr/lib/libdbus-1.so.3+0x17fed) (BuildId: 65f44f39f68b8f63de82c45fc6108bfc66c0247a)
    #6 0x7c7930d652da  (/usr/lib/libdbus-1.so.3+0x182da) (BuildId: 65f44f39f68b8f63de82c45fc6108bfc66c0247a)
    #7 0x7c7932adb053  (/usr/lib/libQt6DBus.so.6+0x3d053) (BuildId: e5361b561fa20a02aaac67f3c1dd32c30532b0f1)
    #8 0x7c7932ad372a  (/usr/lib/libQt6DBus.so.6+0x3572a) (BuildId: e5361b561fa20a02aaac67f3c1dd32c30532b0f1)
    #9 0x7c7932627553 in QObject::event(QEvent*) (/usr/lib/libQt6Core.so.6+0x1c4553) (BuildId: 444a81e6709e165b8eb22906f404c38b6dd43954)
    #10 0x7c79325cd66f in QCoreApplication::notifyInternal2(QObject*, QEvent*) (/usr/lib/libQt6Core.so.6+0x16a66f) (BuildId: 444a81e6709e165b8eb22906f404c38b6dd43954)
    #11 0x7c79325cdab1 in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) (/usr/lib/libQt6Core.so.6+0x16aab1) (BuildId: 444a81e6709e165b8eb22906f404c38b6dd43954)
    #12 0x7c79328b0b17  (/usr/lib/libQt6Core.so.6+0x44db17) (BuildId: 444a81e6709e165b8eb22906f404c38b6dd43954)
    #13 0x7c793110af8c  (/usr/lib/libglib-2.0.so.0+0x5ef8c) (BuildId: ec40d2cf4a8f72fc7a908f45de5c57068a5cf617)
    #14 0x7c793110c656  (/usr/lib/libglib-2.0.so.0+0x60656) (BuildId: ec40d2cf4a8f72fc7a908f45de5c57068a5cf617)
    #15 0x7c793110c864 in g_main_context_iteration (/usr/lib/libglib-2.0.so.0+0x60864) (BuildId: ec40d2cf4a8f72fc7a908f45de5c57068a5cf617)
    #16 0x7c79328ad9d1 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (/usr/lib/libQt6Core.so.6+0x44a9d1) (BuildId: 444a81e6709e165b8eb22906f404c38b6dd43954)
    #17 0x7c79325d8a85 in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) (/usr/lib/libQt6Core.so.6+0x175a85) (BuildId: 444a81e6709e165b8eb22906f404c38b6dd43954)
    #18 0x7c79326edf7d in QThread::exec() (/usr/lib/libQt6Core.so.6+0x28af7d) (BuildId: 444a81e6709e165b8eb22906f404c38b6dd43954)
    #19 0x7c7932ad563d  (/usr/lib/libQt6DBus.so.6+0x3763d) (BuildId: e5361b561fa20a02aaac67f3c1dd32c30532b0f1)
    #20 0x7c7932793ca8  (/usr/lib/libQt6Core.so.6+0x330ca8) (BuildId: 444a81e6709e165b8eb22906f404c38b6dd43954)
    #21 0x7c793463011a in asan_thread_start /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_interceptors.cpp:239
    #22 0x7c7931dd598a  (/usr/lib/libc.so.6+0x9698a) (BuildId: 2f722da304c0a508c891285e6840199c35019c8d)

Direct leak of 96 byte(s) in 1 object(s) allocated from:
    #0 0x7c79346f25dd in calloc /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_malloc_linux.cpp:74
    #1 0x7c792d1adaed  (/usr/lib/qt6/plugins/platforms/../../../libwayland-client.so.0+0x5aed) (BuildId: 3b07142880be2014296cc8464e4410c69ed78d0d)
    #2 0x7c792d1adfad in wl_proxy_marshal_array_flags (/usr/lib/qt6/plugins/platforms/../../../libwayland-client.so.0+0x5fad) (BuildId: 3b07142880be2014296cc8464e4410c69ed78d0d)
    #3 0x7c792d1aefd2 in wl_proxy_marshal_flags (/usr/lib/qt6/plugins/platforms/../../../libwayland-client.so.0+0x6fd2) (BuildId: 3b07142880be2014296cc8464e4410c69ed78d0d)
    #4 0x78792cd76d5b  (/usr/lib/qt6/plugins/platforms/../../../libQt6WaylandClient.so.6+0xa1d5b) (BuildId: 9ab40f62ee892b00276ad0ac9c92b1f29e7bdf8b)
    #5 0x78792cd78f34 in QtWaylandClient::QWaylandWindow::initializeWlSurface() (/usr/lib/qt6/plugins/platforms/../../../libQt6WaylandClient.so.6+0xa3f34) (BuildId: 9ab40f62ee892b00276ad0ac9c92b1f29e7bdf8b)
    #6 0x78792cd7a1b8 in QtWaylandClient::QWaylandWindow::QWaylandWindow(QWindow*, QtWaylandClient::QWaylandDisplay*) (/usr/lib/qt6/plugins/platforms/../../../libQt6WaylandClient.so.6+0xa51b8) (BuildId: 9ab40f62ee892b00276ad0ac9c92b1f29e7bdf8b)
    #7 0x78792cd7a358 in QtWaylandClient::QWaylandShmWindow::QWaylandShmWindow(QWindow*, QtWaylandClient::QWaylandDisplay*) (/usr/lib/qt6/plugins/platforms/../../../libQt6WaylandClient.so.6+0xa5358) (BuildId: 9ab40f62ee892b00276ad0ac9c92b1f29e7bdf8b)
    #8 0x78792cd6ace5 in QtWaylandClient::QWaylandIntegration::createPlatformWindow(QWindow*) const (/usr/lib/qt6/plugins/platforms/../../../libQt6WaylandClient.so.6+0x95ce5) (BuildId: 9ab40f62ee892b00276ad0ac9c92b1f29e7bdf8b)
    #9 0x7c7932d643c5 in QWindowPrivate::create(bool) (/usr/lib/libQt6Gui.so.6+0x2083c5) (BuildId: 5d899a482a838ba70e04ccb1b2a5ffe5810c3bc6)
    #10 0x7c7933c7f1e6 in QWidgetPrivate::create() (/usr/lib/libQt6Widgets.so.6+0x1481e6) (BuildId: 8b2896a63d1d16c55d6dc5adcdc64dc1397afbb1)
    #11 0x7c7933c7e0ee in QWidget::create(unsigned long long, bool, bool) (/usr/lib/libQt6Widgets.so.6+0x1470ee) (BuildId: 8b2896a63d1d16c55d6dc5adcdc64dc1397afbb1)
    #12 0x7c7933c82608 in QWidget::setWindowState(QFlags<Qt::WindowState>) (/usr/lib/libQt6Widgets.so.6+0x14b608) (BuildId: 8b2896a63d1d16c55d6dc5adcdc64dc1397afbb1)
    #13 0x5e6320b0b9d1 in MainWindow::hideWindow() /home/nic/projects/keepassxc/src/gui/MainWindow.cpp:1767
    #14 0x5e63208b9767 in main /home/nic/projects/keepassxc/src/main.cpp:213
    #15 0x7c7931d66634  (/usr/lib/libc.so.6+0x27634) (BuildId: 2f722da304c0a508c891285e6840199c35019c8d)
    #16 0x7c7931d666e8 in __libc_start_main (/usr/lib/libc.so.6+0x276e8) (BuildId: 2f722da304c0a508c891285e6840199c35019c8d)
    #17 0x5e63208b61d4 in _start (/home/nic/projects/keepassxc/build/deploy/keepassxc+0x9d91d4) (BuildId: 087ec4c6d357e35bef2380bf05d0187ba9db44df)

Indirect leak of 1970 byte(s) in 1 object(s) allocated from:
    #0 0x7c79346f1a45 in realloc /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_malloc_linux.cpp:81
    #1 0x7c7930d80566  (/usr/lib/libdbus-1.so.3+0x33566) (BuildId: 65f44f39f68b8f63de82c45fc6108bfc66c0247a)
    #2 0x7c7930d805f4  (/usr/lib/libdbus-1.so.3+0x335f4) (BuildId: 65f44f39f68b8f63de82c45fc6108bfc66c0247a)
    #3 0x7c7930d821db in _dbus_string_copy_len (/usr/lib/libdbus-1.so.3+0x351db) (BuildId: 65f44f39f68b8f63de82c45fc6108bfc66c0247a)
    #4 0x7c7930d743ff in _dbus_message_loader_queue_messages (/usr/lib/libdbus-1.so.3+0x273ff) (BuildId: 65f44f39f68b8f63de82c45fc6108bfc66c0247a)
    #5 0x7c7930d7e8ae  (/usr/lib/libdbus-1.so.3+0x318ae) (BuildId: 65f44f39f68b8f63de82c45fc6108bfc66c0247a)
    #6 0x7c7930d7eaa7  (/usr/lib/libdbus-1.so.3+0x31aa7) (BuildId: 65f44f39f68b8f63de82c45fc6108bfc66c0247a)
    #7 0x7c7930d7ee00  (/usr/lib/libdbus-1.so.3+0x31e00) (BuildId: 65f44f39f68b8f63de82c45fc6108bfc66c0247a)
    #8 0x7c7930d7f38c  (/usr/lib/libdbus-1.so.3+0x3238c) (BuildId: 65f44f39f68b8f63de82c45fc6108bfc66c0247a)
    #9 0x7c7930d62e92  (/usr/lib/libdbus-1.so.3+0x15e92) (BuildId: 65f44f39f68b8f63de82c45fc6108bfc66c0247a)
    #10 0x7c7930d77b9f in dbus_pending_call_block (/usr/lib/libdbus-1.so.3+0x2ab9f) (BuildId: 65f44f39f68b8f63de82c45fc6108bfc66c0247a)
    #11 0x7c7930d64d46 in dbus_connection_send_with_reply_and_block (/usr/lib/libdbus-1.so.3+0x17d46) (BuildId: 65f44f39f68b8f63de82c45fc6108bfc66c0247a)
    #12 0x787921fd5dd6  (/usr/lib/../lib/libnvidia-eglcore.so.580.105.08+0xa30dd6) (BuildId: c818fe996e96e84d896fbc9fda4ecf9ac00476ae)

Indirect leak of 320 byte(s) in 1 object(s) allocated from:
    #0 0x7c79346f1a45 in realloc /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_malloc_linux.cpp:81
    #1 0x7c7930d8182d in _dbus_string_lengthen (/usr/lib/libdbus-1.so.3+0x3482d) (BuildId: 65f44f39f68b8f63de82c45fc6108bfc66c0247a)
    #2 0x7c7930d6d3e4  (/usr/lib/libdbus-1.so.3+0x203e4) (BuildId: 65f44f39f68b8f63de82c45fc6108bfc66c0247a)
    #3 0x7c7930d6d8bf in _dbus_type_writer_recurse (/usr/lib/libdbus-1.so.3+0x208bf) (BuildId: 65f44f39f68b8f63de82c45fc6108bfc66c0247a)
    #4 0x7c7930d6dcad  (/usr/lib/libdbus-1.so.3+0x20cad) (BuildId: 65f44f39f68b8f63de82c45fc6108bfc66c0247a)
    #5 0x7c7930d8a2e5  (/usr/lib/libdbus-1.so.3+0x3d2e5) (BuildId: 65f44f39f68b8f63de82c45fc6108bfc66c0247a)
    #6 0x7c7930d72970 in dbus_message_new_method_call (/usr/lib/libdbus-1.so.3+0x25970) (BuildId: 65f44f39f68b8f63de82c45fc6108bfc66c0247a)
    #7 0x7c7932b074df  (/usr/lib/libQt6DBus.so.6+0x694df) (BuildId: e5361b561fa20a02aaac67f3c1dd32c30532b0f1)
    #8 0x7c7932aec22d  (/usr/lib/libQt6DBus.so.6+0x4e22d) (BuildId: e5361b561fa20a02aaac67f3c1dd32c30532b0f1)
    #9 0x7c7932acb403 in QDBusConnection::asyncCall(QDBusMessage const&, int) const (/usr/lib/libQt6DBus.so.6+0x2d403) (BuildId: e5361b561fa20a02aaac67f3c1dd32c30532b0f1)
    #10 0x7c7933290fa8 in QDesktopUnixServices::QDesktopUnixServices() (/usr/lib/libQt6Gui.so.6+0x734fa8) (BuildId: 5d899a482a838ba70e04ccb1b2a5ffe5810c3bc6)
    #11 0x78792cd6aba4 in QtWaylandClient::QWaylandIntegration::QWaylandIntegration(QString const&) (/usr/lib/qt6/plugins/platforms/../../../libQt6WaylandClient.so.6+0x95ba4) (BuildId: 9ab40f62ee892b00276ad0ac9c92b1f29e7bdf8b)
    #12 0x7c792d1ba179  (/usr/lib/qt6/plugins/platforms/libqwayland.so+0x2179) (BuildId: aaaf8cb1c9681dd8d77744c4dd6fb8a490435520)
    #13 0x7c7932cf9fa7 in QGuiApplicationPrivate::createPlatformIntegration() (/usr/lib/libQt6Gui.so.6+0x19dfa7) (BuildId: 5d899a482a838ba70e04ccb1b2a5ffe5810c3bc6)
    #14 0x7c7932cfb437 in QGuiApplicationPrivate::createEventDispatcher() (/usr/lib/libQt6Gui.so.6+0x19f437) (BuildId: 5d899a482a838ba70e04ccb1b2a5ffe5810c3bc6)
    #15 0x7c79325d1a04 in QCoreApplicationPrivate::init() (/usr/lib/libQt6Core.so.6+0x16ea04) (BuildId: 444a81e6709e165b8eb22906f404c38b6dd43954)
    #16 0x7c7932cfb4cd in QGuiApplicationPrivate::init() (/usr/lib/libQt6Gui.so.6+0x19f4cd) (BuildId: 5d899a482a838ba70e04ccb1b2a5ffe5810c3bc6)
    #17 0x7c7933c32405 in QApplicationPrivate::init() (/usr/lib/libQt6Widgets.so.6+0xfb405) (BuildId: 8b2896a63d1d16c55d6dc5adcdc64dc1397afbb1)
    #18 0x5e63209c56fa in Application::Application(int&, char**) /home/nic/projects/keepassxc/src/gui/Application.cpp:56
    #19 0x5e63208b6c98 in main /home/nic/projects/keepassxc/src/main.cpp:61
    #20 0x7c7931d66634  (/usr/lib/libc.so.6+0x27634) (BuildId: 2f722da304c0a508c891285e6840199c35019c8d)
    #21 0x7c7931d666e8 in __libc_start_main (/usr/lib/libc.so.6+0x276e8) (BuildId: 2f722da304c0a508c891285e6840199c35019c8d)
    #22 0x5e63208b61d4 in _start (/home/nic/projects/keepassxc/build/deploy/keepassxc+0x9d91d4) (BuildId: 087ec4c6d357e35bef2380bf05d0187ba9db44df)

SUMMARY: AddressSanitizer: 2570 byte(s) leaked in 4 allocation(s).

@diegoviola
Copy link

I've tried to compile the current state with qt 6.10 on arch.

I've been testing your fork on Arch Linux as well, and the only test that's been failing here is testurltools, setting those to true is enough to make them pass:

diff --git a/tests/TestUrlTools.cpp b/tests/TestUrlTools.cpp
index b514f6cc..a787ccb1 100644
--- a/tests/TestUrlTools.cpp
+++ b/tests/TestUrlTools.cpp
@@ -141,25 +141,25 @@ void TestUrlTools::testIsUrlValidWithLooseComparison()
     urls["\"https://github.com/login\""] = true;
     urls["https://*.github.com/"] = true;
     urls["*.github.com"] = true;
-    urls["https://*.com"] = false;
+    urls["https://*.com"] = true;
     urls["https://*.computer.com"] = true; // TLD in domain (com) should not affect
     urls["\"\""] = false;
     urls["\"*.example.com\""] = false;
     urls["http://*"] = false;
     urls["*"] = false;
     urls["****"] = false;
-    urls["*.co.jp"] = false;
-    urls["*.com"] = false;
+    urls["*.co.jp"] = true;
+    urls["*.com"] = true;
     urls["*.computer.com"] = true;
     urls["*.computer.com/*com"] = true; // TLD in path should not affect this
     urls["*com"] = false;
-    urls["*.com/"] = false;
-    urls["*.com/*"] = false;
+    urls["*.com/"] = true;
+    urls["*.com/*"] = true;
     urls["**.com/**"] = false;
     urls["*.*"] = false;
-    urls["https://example.*"] = false;
-    urls["https://*.example.*"] = false;
-    urls["https://example.c*"] = false;
+    urls["https://example.*"] = true;
+    urls["https://*.example.*"] = true;
+    urls["https://example.c*"] = true;
 
     QHashIterator<QString, bool> i(urls);
     while (i.hasNext()) {

@stoeckmann
Copy link
Contributor

Please note that Qt 6 switched from int to qsizetype for sizes. This PR does not take it into account, which allows integer overflows in various loops when operating with files or data larger than 2 GB. While this shouldn't happen in regular use cases, importing huge files could trigger such issues.

@ParadaCarleton
Copy link

ParadaCarleton commented Dec 23, 2025

I've tried to compile the current state with qt 6.10 on arch.

I've been testing your fork on Arch Linux as well, and the only test that's been failing here is testurltools, setting those to true is enough to make them pass:

diff --git a/tests/TestUrlTools.cpp b/tests/TestUrlTools.cpp
index b514f6cc..a787ccb1 100644
--- a/tests/TestUrlTools.cpp
+++ b/tests/TestUrlTools.cpp
@@ -141,25 +141,25 @@ void TestUrlTools::testIsUrlValidWithLooseComparison()
     urls["\"https://github.com/login\""] = true;
     urls["https://*.github.com/"] = true;
     urls["*.github.com"] = true;
-    urls["https://*.com"] = false;
+    urls["https://*.com"] = true;
     urls["https://*.computer.com"] = true; // TLD in domain (com) should not affect
     urls["\"\""] = false;
     urls["\"*.example.com\""] = false;
     urls["http://*"] = false;
     urls["*"] = false;
     urls["****"] = false;
-    urls["*.co.jp"] = false;
-    urls["*.com"] = false;
+    urls["*.co.jp"] = true;
+    urls["*.com"] = true;
     urls["*.computer.com"] = true;
     urls["*.computer.com/*com"] = true; // TLD in path should not affect this
     urls["*com"] = false;
-    urls["*.com/"] = false;
-    urls["*.com/*"] = false;
+    urls["*.com/"] = true;
+    urls["*.com/*"] = true;
     urls["**.com/**"] = false;
     urls["*.*"] = false;
-    urls["https://example.*"] = false;
-    urls["https://*.example.*"] = false;
-    urls["https://example.c*"] = false;
+    urls["https://example.*"] = true;
+    urls["https://*.example.*"] = true;
+    urls["https://example.c*"] = true;
 
     QHashIterator<QString, bool> i(urls);
     while (i.hasNext()) {

It looks like the AUR package is no longer compiling.

@droidmonkey
Copy link
Member

Need to test with this issue post-merge: #10763

@varjolintu
Copy link
Member Author

Gotta do some reviews for #11003 so we can rebase this branch to develop.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Qt 6 upgrade