From 14f5eaaf58ff1c1c75bb9c2a8814878eae956c4b Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Tue, 14 Nov 2023 11:14:38 +0100 Subject: [PATCH] Implement a TODO: cache the list of MS TZ IDs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The MS TZ-backend's lookup of available Windows IDs included a TODO advocating caching the result, since it is unlikely to change at runtime. Given that MS's time_t functions don't believe in times before 1970 and two-digit year parsing (such as the ASN.1 parser does, apparently many times, during SSL handshakes) assumes the 1900s (and certs in use today have mostly been issued this century), SSL involves DTP falling back repeatedly to lookups of local time's offsets from UTC (before it discovers it shouldn't have been using local time anyway) via the system timezone object, this cacheable list can be accessed many times. (A user has reported thousands per SSL socket created.) So let's implement that TODO and trust that updates to the registry's set of available zones aren't a common occurrence at runtime. Pick-to: 6.5 Change-Id: Iefe235c71da1bf5c3372c52dba89ad0657e06c0b Reviewed-by: MÃ¥rten Nordheim Reviewed-by: Thiago Macieira (cherry picked from commit d59e539b3a1252aa22783c4fdf1e22b35e5a4292) Reviewed-by: Qt Cherry-pick Bot --- src/corelib/time/qtimezoneprivate_win.cpp | 30 ++++++++++++----------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/corelib/time/qtimezoneprivate_win.cpp b/src/corelib/time/qtimezoneprivate_win.cpp index b1abcb7a970..82666407d2c 100644 --- a/src/corelib/time/qtimezoneprivate_win.cpp +++ b/src/corelib/time/qtimezoneprivate_win.cpp @@ -186,22 +186,24 @@ bool isSameRule(const QWinTimeZonePrivate::QWinTransitionRule &last, QList availableWindowsIds() { - // TODO Consider caching results in a global static, very unlikely to change. - QList list; - QWinRegistryKey key(HKEY_LOCAL_MACHINE, tzRegPath); - if (key.isValid()) { - DWORD idCount = 0; - if (RegQueryInfoKey(key, 0, 0, 0, &idCount, 0, 0, 0, 0, 0, 0, 0) == ERROR_SUCCESS - && idCount > 0) { - for (DWORD i = 0; i < idCount; ++i) { - DWORD maxLen = MAX_KEY_LENGTH; - TCHAR buffer[MAX_KEY_LENGTH]; - if (RegEnumKeyEx(key, i, buffer, &maxLen, 0, 0, 0, 0) == ERROR_SUCCESS) - list.append(QString::fromWCharArray(buffer).toUtf8()); + static const QList cache = [] { + QList list; + QWinRegistryKey key(HKEY_LOCAL_MACHINE, tzRegPath); + if (key.isValid()) { + DWORD idCount = 0; + if (RegQueryInfoKey(key, 0, 0, 0, &idCount, 0, 0, 0, 0, 0, 0, 0) == ERROR_SUCCESS + && idCount > 0) { + for (DWORD i = 0; i < idCount; ++i) { + DWORD maxLen = MAX_KEY_LENGTH; + TCHAR buffer[MAX_KEY_LENGTH]; + if (RegEnumKeyEx(key, i, buffer, &maxLen, 0, 0, 0, 0) == ERROR_SUCCESS) + list.append(QString::fromWCharArray(buffer).toUtf8()); + } } } - } - return list; + return list; + }(); + return cache; } QByteArray windowsSystemZoneId()