Commit Graph

3524 Commits (08bb24dd0a5c97bfefa8bb29d6c43af4525abd64)

Author SHA1 Message Date
Anton Kudryavtsev 470fab51fb Tidy up QAuthenticatorPrivate::calculateResponse
call toBase64() with temp value

Change-Id: Idedfd91f60900ec51923803a6bb9ed6631e64d94
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
2023-09-04 18:16:28 +03:00
Anton Kudryavtsev b4f6399a51 qauthenticator: use QBAV more
Change-Id: Iaa208785f6e1dc8eb5f32ab5e099c8df277bb2f1
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-09-04 18:16:11 +03:00
Anton Kudryavtsev 50fa7996d0 qhttpnetworkconnection: extract method makeAcceptLanguage
and micro optimize it:
- avoid allocation in case of C locale
- don't call replace in case of C locale

Change-Id: I9afefd53b673e5f1236afdb3130d77779614acc7
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-09-04 18:16:08 +03:00
Anton Kudryavtsev 43d15dd572 qhttpnetworkconnection: cache acceptedEncoding header
Encodings are configured at compile time, so no need to re-create acceptedEncoding header for every request, just cache it.

Change-Id: Ibfaf7cdec0504cf90c4b6a59848e7c945d060ebe
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-09-04 18:16:06 +03:00
Anton Kudryavtsev 5f032cdeff QDecompressHelper: port some methods to QBAV
Change-Id: I907019f19cbf4f6086fd6480ea9e01f5ab63b004
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-09-04 18:16:03 +03:00
Anton Kudryavtsev d9620f0660 qnetworkcookie: reduce allocations
Use CaseInsensitive compare more.
While touching code, replcace QBA literal with QBAV

Change-Id: Iecd2740c995f1e24b4285440b9440e4745f93208
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-09-04 18:16:00 +03:00
Anton Kudryavtsev 4ee081c2f7 qauthenticator: reduce allocations in parseHttpResponse
by QBAV usage. While touching code, port index based loop to range based

Change-Id: I06a784b94678b901d1074cca224c926e8534bd8e
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-09-04 18:15:48 +03:00
Anton Kudryavtsev 3e62ecbc25 qnetworkreplyhttpimpl: optimize fetchCacheMetaData
Reduce allocations by usage of case insensitive compare method

While touching code, reorder condition to use cheap int compare first

Change-Id: I01a5d18ae69658a9cd1c27b40a9cdf369231b5fe
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-09-02 15:35:59 +03:00
André Klitzing cda98280ed Fix living QLibProxyWrapper after shutdown of QCoreApplication
Pick-to: 6.6
Task-number: QTBUG-84234
Change-Id: I8f5e2947b6529a0a8871d040050205934ee60354
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-09-01 22:05:29 +02:00
Anton Kudryavtsev 0e5f60a6ca qhttpheaderparser: use algorithms more
No raw loops. Also de-duplicate functors by lambda generator

Change-Id: I053890a0a472bfe2846d7007fda8cca779d812a8
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-09-01 16:06:27 +00:00
Anton Kudryavtsev cf066f7d03 QHostInfo::localDomainName: use QBAV more
to reduce allocations

Change-Id: If75c3818333880ba34f2e58038b05869979ae14d
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-09-01 17:47:28 +03:00
Anton Kudryavtsev 8c5e5af11f qnetworkreplyhttpimpl: use const more
to avoid implicit detach

Change-Id: Ifac91e514b069d0426c70bd7e11cc04baca7994b
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-08-31 21:38:49 +03:00
Anton Kudryavtsev ec6267499e qnetworkreplyhttpimpl: port parseHttpOptionHeader to QBAV
Change-Id: Ib6ac31048b9e2063350e8b956791baeb3d5fbfae
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-08-31 21:38:45 +03:00
Anton Kudryavtsev e28292b3d7 qnetworkreplyhttpimpl: use _ba literal more
to reduce allocations

Change-Id: I742a0ad34bfda8e7def0a7b075a331ab08d18c9a
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-08-31 21:38:26 +03:00
Anton Kudryavtsev 51acd52cf7 qnetworkreplyhttpimpl: use range based for more
to improve readability. While touching code, remove needless copy of container

Change-Id: I04e44819621b5ea9a71f89352e8dd25d4c41de3d
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-08-31 21:38:21 +03:00
Anton Kudryavtsev 22cce68b2c qhttpnetworkrequest: use range based for more
to improve readability

Change-Id: Iaffb3ab8e4a188ee7cba3d9afc527cf3038a8040
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-08-31 11:48:09 +00:00
Anton Kudryavtsev 60133c364a qnetworkrequest: use _ba literal more
to avoid allocations

Change-Id: I747d212e5752bcb42977d6714d241918363d47db
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-08-31 14:48:05 +03:00
Anton Kudryavtsev e84d9ea5e6 qnetworkrequest: extract method
De-duplicate code for cookie header making

Change-Id: I3ac59445089ee151a2f719454fa50cb9f37f72e4
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-08-31 14:48:03 +03:00
Thiago Macieira fcb548878b CMake/Network: limit the testing for some network iface features
These features are now only used for qnetworkinterface_unix.cpp, so they
aren't needed for Windows or for Linux with AF_NETLINK support. This
commit removes the last couple of placess outside of that file where
they were used (the qnativesocketengine_unix.cpp code looked stale
anyway).

These tests cost us approximately 1300 ms during CMake time. This commit
does not change that because the tests are checked even if the condition
has already been forced OFF by previous conditions.

[ChangeLog][Build system] The QT_NO_GETIFADDRS and QT_NO_IPV6IFNAME
macros are deprecated. On a standard Linux build, they will be defined
to 1, even if the system does support getifaddrs() and ifnametoindex().

Task-number: QTBUG-107248
Task-number: QTBUG-115705
Change-Id: Ifbf974a4d10745b099b1fffd17775822a1a6e55f
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-08-30 23:26:25 -07:00
Anton Kudryavtsev a6886859ad hpack: use QBAV more
While touching code, use constexpr more

Change-Id: I1c5d80f257f742a2999147c12340bba38e8b1e2f
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
2023-08-29 18:15:05 +00:00
Anton Kudryavtsev 6cc1a84005 qnetworkrequest: reduce branches in loop
Unconditionally append separator and then chop last one

Change-Id: I33d004df07ce0c3c0076dc374ae7a2f8c413aeba
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-08-28 19:11:15 +03:00
Anton Kudryavtsev 3730212312 qnetworkrequest: port parseMatchImpl to QBAV
to save allocations, and use tokenize to avoid temp container

Change-Id: I2a43612b9d15538a93d4afd2c544714507141f0f
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-08-28 14:49:36 +03:00
Anton Kudryavtsev 8db5896bbe qnetworkrequest: port parseHeaderName to QBAV
Change-Id: I39af8649468636d09db46aac770f5df7a3582b50
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-08-28 12:47:16 +03:00
Anton Kudryavtsev e3bb75340e qnetworkrequest: extract method
for If-Match and If-None-Match parsing

Change-Id: I523f5c639a01bafe6f25f13c0d25b3c62fa75282
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-08-27 15:09:13 +03:00
Anton Kudryavtsev 881260f9e4 qnetworkrequest: use new parseCookies overload
While touching code, replace split with tokenize

Change-Id: I3382ab6937892b0d6ba37591fbe3697a958c69bb
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-08-27 06:30:34 +00:00
Anton Kudryavtsev d253156687 QAuthenticator: replace split with tokenize
to avoid needless allocations

Change-Id: I39eb90ef073db5359e7a559e33233b1e75b7461c
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-08-27 09:29:45 +03:00
Anton Kudryavtsev 3273c03b51 QHostAddress::toString: use QSB more
Change-Id: Id7d9675c5a8dd09d0edaaa34a28a07fead068109
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-08-27 06:28:49 +00:00
Anton Kudryavtsev 98e7da8e32 QNetworkCookie: add QBAV overload for parseCookies
Rewrite impl to reduce allocations by QL1S::tokenize

Change-Id: I8d131ef6d7fe9a1a9daa438efea026392deb5e55
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-08-27 01:01:10 +03:00
Anton Kudryavtsev 5442ebe5e8 QNetworkHeadersPrivate::findRawHeader: use algorithms more
No raw loops

Change-Id: Ieeaff911f4c6f2c88d358fd1bc1250ffe75f5c6f
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-08-26 21:47:15 +03:00
Anton Kudryavtsev 449f975566 QHttpNetworkHeader::headerField: port to QBAV
In QHttpNetworkRequest and QHttpNetworkReply this method is used with const char* literals, so no need to create QByteArray

Change-Id: Ifef7cb23aa434577455625077ef1adaab085c8ae
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-08-26 18:45:00 +00:00
Anton Kudryavtsev a10c8647b3 qhttpnetworkreques: use range based for more
to improve readability

Change-Id: I4d4342f45296e2d6f439c6a74292c6c922e95194
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-08-26 18:35:40 +00:00
Thiago Macieira 9d4579c1cd CMake: modernize ipv6ifname and getifaddrs config checks with QT_CONFIG
I've left the QT_NO_ macros because they were public. No one should be
using them (and they are now 1 on Linux, so you had better not be using
them), but just in case.

Change-Id: Ifbf974a4d10745b099b1fffd177758a7a26e4244
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
2023-08-25 15:53:03 -07:00
Anton Kudryavtsev 5a291761e0 QNAM: use _ba literals more
to reduce allocations

Change-Id: I4e03d7d51380e14b4c2aa50c5836d09f2aaf608d
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-08-25 22:29:51 +03:00
Anton Kudryavtsev efb5424800 QAuthenticator: postpone creation of QBA
Create QBA only when it's needed
While touching code, use std::move more

Change-Id: I5f014822a47d41fa1fca46a85a7921c70d1d9a55
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-08-25 22:29:51 +03:00
Anton Kudryavtsev 12184ebe7f QAuthenticator: use QSB more
avoid temp allocations

Change-Id: I8ca4d4b748f79d1c7a4455a5105998c58c91c7a4
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-08-25 22:29:51 +03:00
Anton Kudryavtsev 5d534d8913 QNetworkCookiePrivate::parseSetCookieHeaderLine: port to QBAV
Change-Id: If777e43d5c24820dfab02bbf49501b09d82cc2a0
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-08-25 20:04:47 +03:00
Anton Kudryavtsev 6db83b57de qnetworkrequest: use QBAV more
to reduce allocations

Change-Id: Ifcb7da9d302efafd7f890b6b3fb52b7a740274d1
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-08-25 17:04:47 +00:00
Anton Kudryavtsev 639a7a6f6c QNetworkHeadersPrivate::findRawHeader: port to QBAV
Change-Id: I15274eaa79d05a2aed909bada94276f98ae25fe8
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-08-25 15:56:27 +00:00
Anton Kudryavtsev 002c2723c9 qnetworkcookie: reduce allocations
by using QBAV::toInt instead of creating temp QBA + atoi

Change-Id: I90dd78e3fd989930071e3bd99c914087409aa948
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-08-25 14:33:51 +03:00
Mate Barany 1b429d6be4 Add Q_CLASSINFO to QNetworkInformation
As part of creating the QML binding, add
Q_CLASSINFO("RegisterEnumClassesUnscoped", "false")
to QNetworkInformation.

Task-number: QTBUG-113813
Change-Id: Ib5d3b2356986c565b9786bc2d925cc4199bae6c9
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2023-08-24 18:29:15 +02:00
Anton Kudryavtsev f5b4a18b56 qnetworkcookie: replace QString with QL1S
to save allocation

Change-Id: I7726d2e9d165ec3ebdd4a6dd7dd98bcd16c50bc6
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-08-24 16:49:49 +03:00
Anton Kudryavtsev 4d5fb42987 qhsts: use const methods more
to prevent possible detach

Change-Id: If349999b873195ca96ea0101273861b95eb16b4f
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-08-24 16:49:20 +03:00
Anton Kudryavtsev 082d15e733 qhsts: use QBAV more
to avoid temp allocation

Change-Id: I1466f07475cfb07711036c44f56c8e2e34f56601
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-08-24 16:48:44 +03:00
Anton Kudryavtsev 6ade83e635 http2protocol: use QSB to reduce allocations
Change-Id: I9bc312e6c7e4b7c8f613b88e206a2a23f9e23722
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-08-24 16:48:16 +03:00
Anton Kudryavtsev 4ec9e4b2b1 qhttpnetworkheader: port some methods to QBAV
to save some allocations. In qhttpnetworkreply.cpp methods are used with const char* literals, so no need to create QByteArray

Change-Id: I94c2eca1a5c6ab73d4133d87fee007af8cb65ea1
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-08-23 07:00:37 +00:00
Anton Kudryavtsev 38429c16b5 qhttpheaderparser: port some methods to QBAV
Change-Id: If9d74e42e8633cdbc0caeebedc9a36918c0b05a5
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-08-22 20:58:15 +03:00
Anton Kudryavtsev 3c56f561e4 qhttpheaderparser: replace QBA with QBAV
in QSB expression to avoid temp allocation

Change-Id: Ib4106c5c9fa0281203dc61bad50418805c6119a9
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-08-22 17:17:33 +00:00
Alexandru Croitor 409469ba14 CMake: Fix build when developer-build is on but private_tests is OFF
If qt is first configured without -developer-build, and then
reconfigured with -developer-build, QT_FEATURE_developer_build will be
ON but QT_FEATURE_private_tests remains OFF, and is not reset to ON.

This causes a link failure in Network, because the source files
defining the QNetworkAccessDebugPipeBackendFactory class are only
added if QT_FEATURE_private_tests is ON, which is not the case above,
but the C++ code checks for the QT_INTERNAL_BUILD define which is
defined when -developer-build is ON.

Align the C++ code to check for the private_tests feature.

Pick-to: 6.5 6.6
Task-number: QTBUG-112957
Change-Id: Ib6ed891a84c6b118836497d6ead48019bb1b9052
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
2023-08-22 18:09:36 +02:00
Marc Mutz 1a3f573bd9 QHostInfo: remove usused -Result and -Runnable ctors
Clean up after all users are ported to the SlotObjUniquePtr overloads.

Pick-to: 6.6 6.5
Change-Id: I3e58249296ea9674c45fb412463ae3201518de72
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2023-08-18 21:02:51 +00:00
Marc Mutz 14cf4f7584 QHostInfo: add -Result and -Runnable ctors taking SlotObjUniquePtr
... and use them around the code.

Avoids the impedance mismatch between users, which .release() their
SlotObjUniquePtr's into the ctors, and the ctor, which constructs its
member SlotObjUniquePtr from that.

The old constructors are left in on purpose and removed in a follow-up
commit to facilitate cherry-picking into branches that might have
additional callers.

Pick-to: 6.6 6.5
Change-Id: I6f8bce317d5116296973a3a2e3f97db1451f579d
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2023-08-18 16:00:09 +00:00
Thiago Macieira 14d1108d35 Deprecate Q_ASSUME()
We've known for a long time that this is producing worse code with GCC
because of how we implemented in Q_ASSUME_IMPL(). So bite the bullet and
actually deprecate the macro, replacing all extant Q_ASSUME() with
Q_ASSERT().

The replacement is in C++23. Backporting the support onto Q_ASSUME_IMPL
was previously rejected by reviewers.

[ChangeLog][Deprecation Notice] The Q_ASSUME() macro is deprecated. This
macro has different side-effects depending on the compiler used (GCC
compared to Clang and MSVC), and there are certain conditions under
which GCC is known to produce worse code than if the macro was absent.
To give a hint to the compiler for optimizations, use the C++23
[[assume]] attribute.

Change-Id: I80612a7d275c41f1baf0fffd177a3a4ad819fb2d
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2023-08-14 17:36:37 -07:00
Marc Mutz 5d8db914c9 QHostInfo: port lookupHostImpl() to SlotObjUniquePtr internally
Avoids the manual deref'ing.

Pick-to: 6.6 6.5
Change-Id: I1a51a468dfa704986f050b29322a424dc6fcd7b7
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-08-14 21:30:44 +02:00
Mate Barany 85e2f79e9e Make QNetworkInformation thread safe
The current implementation is not thread safe - it is possible
to update and query the network information without any locking.

Protect the internals of the backend with a lock and move the
object to the main thread.

Task-number: QTBUG-115748
Change-Id: I9511fc3522ae82cffca42abc54eb79cb156397c4
Reviewed-by: Juha Vuolle <juha.vuolle@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-08-14 16:24:46 +02:00
Marc Mutz 4cf51f4616 QHostInfo: use new QMetaCallEvent::create() overload
Move the SlotObjUniquePtr directly into the QMetaCallEvent, without
having to up and down the ref-count.

Pick-to: 6.6 6.5
Change-Id: I029f71c60defce71ac8778547efe999ce0cf7b4b
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2023-08-10 21:50:59 +02:00
Marc Mutz a2c8524ad7 QHostInfo: de-inline -Result and -Runnable dtors
These classes are not exported, so we don't run into duplicate vtables
here, but the header is included in a few TUs other than qhostinfo.cpp
(all, when building with PCH), so make sure we compile dtors only once.

Pick-to: 6.6 6.5
Change-Id: I51f6a6d27fc084ad469f82dc7aef3327bdd9a906
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
2023-08-07 23:56:11 +02:00
Marc Mutz a9982a3b63 Add copy(SlotObjUniquePtr), use it in QHostInfoResult & SlotObjSharedPtr
It's a free function, because a) it rhymes with move(ptr) and, of
course, SlotObjUniquePtr being a std::unique_ptr, b) we can't add
member functions to it (and no, inheriting from a type whose dtor is
neither protected nor virtual is nothing you will catch yours truly
doing).

Pick-to: 6.6 6.5
Change-Id: I2026126857a7bba204d683bad118e8a2c5cb2924
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
2023-08-06 11:33:03 +00:00
Mårten Nordheim 5bb4020cbe QHostInfo: use SlotObjUniquePtr
Drops the direct deref'ing.

Pick-to: 6.6 6.5
Change-Id: I9f159244d50572659fa8e9cabfbef47e769ac54e
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
2023-08-06 09:05:03 +02:00
Marc Mutz 693c9e6b1b QHostInfo: fix remaining slotObj leaks
We failed to delete the slot object when lookUpHost() was called in
these (exceptional) circumstances:

- on a thread with no event dispatcher

- after application shut-down, when the QHostInfoLookupManager
  Q_APPLICATION_STATIC was destroyed already

Fix by adding the missing destroyIfLastRef() calls into these code
paths, too.

Amends ad5eb297e1.

This would be so much easier if we had SlotObjUniquePtr...

Pick-to: 6.6 6.5 6.2 5.15
Task-number: QTBUG-115263
Change-Id: Ief8bf125bc196742c0ce59c1fd87ab93242fc0da
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
2023-08-04 19:49:32 +02:00
Ahmad Samir 7fe1198f6e QAbstractSocket: remove a redundant stack variable
Just use the static const int directly.

Change-Id: Icf37ac5db4457bbc8631659e175d038cfeed46e4
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
2023-08-03 02:12:22 +03:00
Jacek Poplawski e73e972aa6 Don't include resolv.h when libresolv is disabled
Change-Id: I5b216ed02452549b69847b34139613669905023c
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-07-26 09:03:38 +02:00
Mårten Nordheim 061ab84e98 QHostInfo: fix leaking slot object
We were not ref'ing or deref'ing the slot object in the various places
that owned it. So, if, in the end, the QHostInfoResult object didn't
call the slot we would leak the slot object.

Pick-to: 6.6 6.5 6.2 5.15
Fixes: QTBUG-115263
Change-Id: I45f43756c7589470045d97b59257ccfd85a325b7
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2023-07-19 14:16:55 +02:00
Mårten Nordheim 90af40ccd0 Handle authenticate challenge for Negotiate
Because we didn't handle Negotiate in the "Start" phase during
handleAuthenticateChallenge, we would not emit the auth signal before
our second attempt, assuming the server prompts us for one.

Emitting the authenticationRequired signal is needed for users
to be able to set the Service Principal Name (SPN) option.
Alternatively, username and password if not relying on Single sign-on.

Done-by: Emil Wipplinger <>
Pick-to: 6.6 6.5
Fixes: QTBUG-114559
Change-Id: I833c08dfeda36a6548c5ad6b8af4b8aa9d644c45
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
2023-07-18 19:18:59 +02:00
Thiago Macieira 5bcacdbd1a QNetworkInterface/Linux: fix mismatch of pointer and pointee
It was hard to see the problem because of the lambda, combined with
reinterpret_cast on the output of non-typesafe C macro. NLMSG_DATA
returns a void*, so use static_cast to be sure not to do something
wrong.

This only affected the code that dealt with unexpected replies from the
Linux kernel, which it doesn't send. So I don't expect this fixes any
improper QNetworkInterface behavior.

Found by CodeChecker.

Pick-to: 6.5 6.6
Change-Id: I61b74deaf2514644a24efffd1770d75e5a4f2636
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-07-11 13:44:29 -07:00
Giuseppe D'Angelo 536a4299be Enable QT_NO_CONTEXTLESS_CONNECT for most of QtBase
It's clean now, keep it as such.
Enabling it for QtCore is still OK, because it just hides a function
template declared in a header.

Change-Id: I8e7dfae179732ba04241a6a3258c2d722e8259df
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-07-11 22:44:29 +02:00
Mårten Nordheim babdeb7a10 http2: inline a couple static variables
It looks cleaner when it's declared where it's defined.

Change-Id: I5006fc086c73e6d4891bc64ff3a8c6b4b17623fe
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
2023-07-10 14:53:34 +02:00
Mårten Nordheim 8f4e29cc85 http2: Use QByteArrayView in lambda where we only parse
Thinking back I'm 99% certain I deliberately used QBA because I was
going to cherry-pick it back and didn't feel like dealing with failing
builds. Coming up we will have a lot of other changes here so let's
change this as well.

Change-Id: Ifc60ad8ee2a1e5b75ac766b4a8b7e1559f80e942
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Konrad Kujawa <konrad.kujawa@qt.io>
2023-07-10 14:53:33 +02:00
Mårten Nordheim 991053fdff http2: use qAddOverflow instead of local function
Change-Id: Ice7f0f026353f5668a437cc35d9b21cde0a69182
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Konrad Kujawa <konrad.kujawa@qt.io>
2023-07-10 14:53:33 +02:00
Mårten Nordheim f49e62e782 http2: perform clang-tidy suggestion to use emplace_back
Change-Id: I4148f94a7d9944eddccaba6dbc956abcd2ad9937
Reviewed-by: Konrad Kujawa <konrad.kujawa@qt.io>
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
2023-07-10 14:53:33 +02:00
Mårten Nordheim 35450cde05 http2: use find() instead of multiple lookups
Change-Id: Ibef8da7349d143433522bbb0fd2ee228f0d58135
Reviewed-by: Konrad Kujawa <konrad.kujawa@qt.io>
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
2023-07-10 14:53:33 +02:00
Mårten Nordheim 0e007efd7f QSslServer: include moc
Pick-to: 6.6 6.5
Change-Id: I7849a47b50930640f1937ba34976d2465390daf9
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
2023-07-07 18:25:46 +02:00
Mårten Nordheim 467b01f494 http2: fix potential warning about narrowing
By passing both arguments as qint64, then casting to qint32.
Since one of the arguments are qint32, the result will fit in qint32.

Change-Id: I98e9b1484549fa5dad340f02eda1b341cf6b293d
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
Reviewed-by: Konrad Kujawa <konrad.kujawa@qt.io>
2023-07-07 18:25:31 +02:00
Safiyyah Moosa 44fd4a3ba0 Docs: State that OpenSSL3 is available from 5.15.1
Task-number: QTBUG-114138
Pick-to: 6.5 6.6 5.15
Change-Id: I4d2ef35f99065e6c858044bdd07882e6315129f9
Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
2023-07-07 18:15:01 +02:00
Giuseppe D'Angelo d45ac7b898 QtNetwork: code tidies: use the 4-arg connect overload
The 3-arg connect is error-prone and makes the lifetime of the
connection unclear.

Amends dae24df07f

Change-Id: Iec1c2cb266fcaca1a1c407a6158cc8bbb282756b
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-07-05 15:09:31 +02:00
Safiyyah Moosa d2a73883ae Doc: State that Qt5.15 is compatible with OpenSSL3
Task-number: QTBUG-114138
Pick-to: 6.5 6.6
Change-Id: Ida224255d4aac323cb4bebeb7825a07bb55fc041
Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
2023-07-05 15:09:31 +02:00
Marc Mutz 586e07785c QtNetwork: replace clashing statics with lambdas II: isSeparator
Detected with -unity-build-batch-size 103.

Here, we just replace one of the static functions with a lambda,
because the transformed function was far away from the use site while
the unchanged instances (in qhsts.cpp) had several brethren isFoo()
functions and the use was close to the definition.

Pick-to: 6.6 6.5
Task-number: QTBUG-115031
Change-Id: Ib84a64cd8b9f20cad7806659990df76552c0c5e4
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-07-04 18:16:38 +02:00
Marc Mutz 5b7c8eb984 QtNetwork: replace clashing statics with lambdas I: downloadBufferDeleter
Detected with -unity-build-batch-size 103.

Pick-to: 6.6 6.5
Task-number: QTBUG-115031
Change-Id: Ia67082efbdb3f403a8c8010ec15f9f796f97feb6
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-07-04 18:16:37 +02:00
Kai Köhne 9c43bb6134 Network: Remove unneeded Q_QDOC check for http feature
http is enabled by default if you have threading support, which is true for qdoc. There is therefore no reason to believe that a normal
qdoc configuration won't have it configured, and hence no need to
check also explicitly for Q_QDOC.

Pick-to: 6.6
Change-Id: I118388fedaa87225ce81a211d361d593da61105d
Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
2023-06-30 16:46:54 +00:00
Topi Reinio 43ea57b901 Use a global value for warning limit when testing documentation in CI
The most common limit for the maximum number of allowed documentation
warnings is zero. Use a global value for 'warninglimit', adopted by
all Qt module documentation projects that include the configuration
from qtbase/doc/global.

This allows for a temporary increase of the limit across all modules as
needed - for example, when updating the QDoc binary that the CI
provisions to a version that introduces new types of documentation
warnings.

Increase this base limit temporarily to 10 to help re-enable
documentation testing in CI as it's currently disabled.

Task-number: QTBUG-113326
Change-Id: I8b66951ca9324bcfaec3b5a7ec2cff544c62feb0
Reviewed-by: Paul Wicking <paul.wicking@qt.io>
2023-06-27 15:12:31 +00:00
Michael Klein 69de333e1f QNetworkReply: Propagate proxy errors properly
Map QNetworkError::HostNotFoundError and QNetworkError::ConnectionRefusedError
 to ProxyNotFoundError resp. ProxyConnectionRefusedError when it originated
from the communication with the proxy server.

Fixes: QTBUG-68821
Pick-to: 6.5 6.6
Change-Id: I21b91f2667ba0cd329d4ece1fe543472cdab2d22
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-06-27 17:12:31 +02:00
Giuseppe D'Angelo 3ec24e329c SSL: upgrade the default DH parameters
We have been using as default DH parameters the 1024-bit MODP group.
This is now considered insecure, and applications should use the
2048-bit at a minimum [1]. This commit therefore replaces the parameters
with the 2048-bit MODP group from [2].

To double check the data, use openssl asn1parse to verify that the prime
matches. For instance:

1) put the encoded string in a `encoded.txt` file (c&p from the source,
   removing the double quotes)
2) put the hexadecimal value of the 2048-bit group in a `reference.txt`
   file (c&p from [2])
3) compare the output of openssl asn1parse with the reference. For
   instance like this:

    $ diff <(openssl asn1parse < encoded.txt | grep -m 1 INTEGER | perl -pe 's/.*://; s/\n//') <(perl -0777 -pe 's/\s//g' reference.txt) && echo OK
    OK

[1] https://datatracker.ietf.org/doc/html/rfc8247#section-2.4
[2] https://datatracker.ietf.org/doc/html/rfc3526#section-3

[ChangeLog][QtNetwork][QSslDiffieHellmanParameters] The default
Diffie-Hellman parameters are now using the 2048-bit MODP group from
RFC 3526.

Pick-to: 6.6 6.5 6.2 5.15
Change-Id: I47133cd78ba0e954b8f93a3da09fa2c760c9f7a8
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
2023-06-27 10:55:27 +02:00
Giuseppe D'Angelo dae24df07f QtNetwork: code tidies: use the 4-arg connect overload
The 3-arg connect is error-prone and makes the lifetime of the
connection unclear.

Change-Id: I43dabe3d25ffc2b711aa50dec525d72a8810861c
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-06-26 20:47:44 +02:00
Tobias Koenig f7792d2b6d Schannel: Add support for proper listing of ciphers
Reworked the code to list supported ciphers for Schannel
backend to provide the proper cipher names and cipher
properties.
Note: restricting the used ciphers for a TLS connection
is only supported for TLS 1.2 yet!

[ChangeLog][QtNetwork][QSslConfiguration] Add support for
listing supported ciphers with Schannel backend.

Change-Id: Idfc17335ec489315387a3e84b7a76a263be22378
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-06-16 09:27:00 +02:00
Topi Reinio ebc371de0d Doc: RSS listing example: Fix file quoting
The example was moved to qtnetwork but its documentation
still referred to old paths under /examples/corelib.

Add documentation dependency to qtwidgets as RSS listing
example's docs link to a number of widget classes.

Pick-to: 6.6 6.5
Change-Id: Ief1c9dc2ca38ba3da1fe3039500292147ec4cc7d
Reviewed-by: Andreas Eliasson <andreas.eliasson@qt.io>
2023-06-15 11:34:17 +00:00
Lorn Potter 103ffe1b58 wasm: fix networkreply with empty data
Fixes: QTBUG-114078
Pick-to: 6.5 6.6
Change-Id: I78e6844ab1aa5d385d8c558c696299e7fa845f50
Reviewed-by: Mikołaj Boc <Mikolaj.Boc@qt.io>
2023-06-14 11:56:32 +10:00
Marc Mutz b2244a252c qnetworkreplyfileimpl_p.h: fix header guard name
It was missing the _P.

Pick-to: 6.6 6.5 6.2 5.15
Change-Id: Ic07b4145f06ba3b1bea52349cf9b3f8215f30313
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2023-06-08 18:07:57 +02:00
Amir Masoud Abdol 1dfa922606 Remove the manual undef of the min/max macros, or def NOMINMAX
We now add NOMINMAX to PlatformCommonInternal target which will be
linked to everything else, so min/max will not be defined upon the
inclusion of `windows.h`, or other headers.

Pick-to: 6.5 6.6
Change-Id: I10016720dac7ce015e929885b7368ee86d8b6918
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
2023-06-08 01:18:04 +02:00
Thiago Macieira 114d00f043 QDnsLookup/Unix: cache previously decoded domain names
Change-Id: I5f7f427ded124479baa6fffd175f3ce37f0e49aa
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-06-03 19:28:15 -07:00
Thiago Macieira 59a2a32276 QDnsLookup/Windows: add a simple decoded domain cache
Avoid decoding multiple times the domain name when it comes in
sequence. This happens when a given domain label either has multiple
entries in its record set or when it's a CNAME (or both), such as in:

;; ANSWER SECTION:
cname-cname.test.qt-project.org. 3600 IN CNAME  cname.test.qt-project.org.
cname.test.qt-project.org. 1614 IN      CNAME   multi.test.qt-project.org.
multi.test.qt-project.org. 1614 IN      A       198.51.100.2
multi.test.qt-project.org. 1614 IN      A       198.51.100.3
multi.test.qt-project.org. 1614 IN      A       198.51.100.1

Label targets from other records such as MX and SRV usually do show up
again, in the Additional section, but the chance that they are
sequential isn't very good, so we don't cache those.

;; ANSWER SECTION:
mx-multi.test.qt-project.org. 3354 IN   MX      10 multi.test.qt-project.org.
mx-multi.test.qt-project.org. 3354 IN   MX      20 a-single.test.qt-project.org.

;; ADDITIONAL SECTION:
multi.test.qt-project.org. 1145 IN      A       198.51.100.3
multi.test.qt-project.org. 1145 IN      A       198.51.100.1
multi.test.qt-project.org. 1145 IN      A       198.51.100.2
a-single.test.qt-project.org. 3364 IN   A       192.0.2.1

Change-Id: I5f7f427ded124479baa6fffd175f5cf88939ee73
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-06-03 19:28:14 -07:00
Thiago Macieira 8b6bd8ed99 QDnsLookup: allow looking up the root domain
[ChangeLog][QtNetwork][QDnsLookup] It is now possible to look up the
root DNS domain, by setting the name property to an empty string. This
query is usually done while setting the query type to NS.

Change-Id: I5f7f427ded124479baa6fffd175f688395941610
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-06-03 19:28:13 -07:00
Thiago Macieira 01dfcfcecf QDnsLookup: merge some of the domain label expansion code
Use qt_ACE_do directly from QtCore, to avoid going through Latin1
(US-ASCII) multiple times.

Drive-by reduce the size of the buffers from PACKETSZ (512) to the
maximum name a label can be (255 plus 1 for the null, just in case).

Drive-by replace the last QString::fromWCharArray with QStringView,
saving an unnecessary memory allocation before calling
QtPrivate::convertToLatin1().

Change-Id: I3e3bfef633af4130a03afffd175d8be1feb5d74b
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-06-03 19:28:11 -07:00
Thiago Macieira 52fa66d087 QNativeSocketEngine: fix warning about uninitialized variables
In function ‘int qt_safe_connect(int, const sockaddr*, socklen_t)’,
    inlined from ‘bool QNativeSocketEnginePrivate::nativeConnect(const QHostAddress&, quint16)
qnet_unix_p.h:111:38: error: ‘sockAddrSize’ may be used uninitialized [-Werror=maybe-uninitialized]
qnativesocketengine_unix.cpp:396:18: note: ‘sockAddrSize’ was declared here
qnativesocketengine_unix.cpp:476:14: error: ‘aa.qt_sockaddr::a.sockaddr::sa_family’ may be used uninitialized [-Werror=maybe-uninitialized]
qnativesocketengine_unix.cpp:471:17: note: ‘aa’ declared here

Introduced by commit 45a03fc506.

Change-Id: I5f7f427ded124479baa6fffd175fbf006c098854
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-05-31 14:54:56 -07:00
Mårten Nordheim 57ba6260c0 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.

Follow-up to/amends ada2c573c1

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.

Pick-to: 6.5 6.2 5.15
Change-Id: Ic3b2ab125c0cdd58ad654af1cb36173960ce2d1e
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
2023-05-29 16:03:35 +02:00
Thiago Macieira 26dd7fe4ed CMake: remove "res_ninit" feature and collapse to just "libresolv"
Testing for "res_ninit" when WrapResolv.cmake has already checked for
far more complex functions was pointless. Instead, just accept the
library that was found by find_package() as good enough and rename the
feature as "libresolv".

Amends 4a46ba1209 and
68b625901f.

Change-Id: Ib5ce7a497e034ebabb2cfffd1762c0afa2fac6e0
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-05-27 12:57:16 -07:00
Mårten Nordheim 456cfa0bd2 Network: Fix IFF_UP conflict on Linux with unity builds
I cannot repro this myself, but from the bug report it seems to be
defined in two headers, so we should consistently use the same one.

Fixes: QTBUG-113787
Pick-to: 6.5
Change-Id: I9f1cc51e379c33dbbf659946340a5207aaeb448a
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
2023-05-26 23:06:50 +02:00
Thiago Macieira 432d67b43f QDnsLookup: add TimeoutError for timeouts
We were getting InvalidReplyError because it was simply unknown, which
is not very useful. Previously, the Unix code used res_nquery(), which
does not return timeouts as a condition. It returns -1 if a timeout did
happen, but the content in errno could be a left-over from a previous
timeout (see the "Not a typewriter"[1] problem).

With the rewrite to using res_nmkquery() and res_nsend() from the
previous commits, we can rely on errno being set properly by
res_nsend().

$ $objdir/tests/manual/qdnslookup/qdnslookup @0.0.0.1
; <<>> QDnsLookup 6.6.0 <<>> qdnslookup @0.0.0.1
;; status: TimeoutError (Request timed out)
;; QUESTION:
;qt-project.org                 IN A

;; Query time: 10008 ms
;; SERVER: 0.0.0.1#53

Tested on FreeBSD, Linux, macOS, and Windows.

[1] https://en.wikipedia.org/wiki/Not_a_typewriter

Change-Id: I3e3bfef633af4130a03afffd175e31958247f9b1
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-05-26 06:46:33 -07:00
Thiago Macieira 5ecdce0c35 QDnsLookup/Unix large replies: manually handle VC [3/3]
The current code was inefficient when replies exceeded the initial
buffer size because the res_nsend() function switched to VC to get the
full reply, but that wouldn't fit our buffer before we enlarged it. This
commit tells res_nsend() to only use UDP or only use TCP, avoiding the
two unnecessary transactions in the lookup.

Since we don't get that second TCP reply now that would tell us the size
of the reply, we must allocate the largest possible buffer for a DNS
reply.

Change-Id: I3e3bfef633af4130a03afffd175e73d2e9fa9bf1
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-05-26 06:46:32 -07:00
Thiago Macieira df07d98243 QDnsLookup/Unix large replies: use EDNS0 [2/3]
The current code is inefficient when dealing with replies exceeding the
PACKETSZ default size. This commit adds an EDNS0 footer to the DNS query
informing the DNS server how big our buffer is. We choose a larger
buffer than the old PACKETSZ so more will fit before a Virtual Circuit
(TCP socket) is required.

The choice is based on IPv6 requirements for the minimum MTU. Any
network incapable of transmitting frames with that big a payload must
support fragmenting and reassembly at the Layer 2 level, below IP.
Ethernet MTU is usually 1500, so we leave a bit on the table, but this
avoids having to discover our Path MTU to the DNS server.

This is incomplete: DNS queries above the 1232-byte limit still perform
the same query four times.

Change-Id: I3e3bfef633af4130a03afffd175e72f7fbc9265d
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-05-26 06:46:31 -07:00
Thiago Macieira b673fa09c3 QDnsLookup/Unix large replies: use res_nmkquery & res_nsend [1/3]
The current code is inefficient when dealing with replies exceeding the
PACKETSZ default size and especially those that require the use of a
Virtual Circuit (TCP socket). When the TC (Truncated) bit is set in the
DNS reply header, res_nquery() automatically switches to VC so it is
able to return the full size of the reply to us. This means we make the
same request four times:
 1) over UDP, getting ~512 bytes of data
 2) over TCP, getting the full reply but returning ~512 to us
 3) over UDP again, getting (maybe) 1400 bytes of data
 4) over TCP again, getting all the data

This commit splits res_nquery() into its two component functions,
res_nmkquery() and res_nsend(). This is incomplete: the four queries
above still happen.

Change-Id: I3e3bfef633af4130a03afffd175e728d96d6a604
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-05-26 06:46:31 -07:00
Amir Masoud Abdol 7367cba9eb Compile Network with NOMINMAX
On Windows, when building using Unity Build, min/max macro form
`window.h` makes it to some files, and messes up evaluation of code like
`std::numeric_limits<T>::max()` which leads to compilation error.
We don't use min/max macros in Qt base, and it might be the time to pass
NOMINMAX to our targets.

Pick-to: 6.5
Task-number: QTBUG-109394
Change-Id: Ia1ff5de36538075264c8556ef3b0416f3c15168c
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
2023-05-24 08:39:53 +02:00
Thiago Macieira ecaf93c366 QDnsLookup: centralize printing of warnings
Any resolution error that is caused by an invalid request, invalid reply
(only happens on Unix), or a system error can be printed as a warning,
using category "qt.network.dnslookup". Those warnings are disabled by
default.

Change-Id: I5f7f427ded124479baa6fffd175fc40b3e21c969
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-05-23 21:23:45 -07:00