diff options
author | Edward Welbourne <edward.welbourne@qt.io> | 2018-10-09 15:25:18 +0200 |
---|---|---|
committer | Edward Welbourne <edward.welbourne@qt.io> | 2018-10-22 10:07:01 +0000 |
commit | 6c543879a31d7d13a6b87e6332f6913f2f89f5e6 (patch) | |
tree | a4471a1ba1a5c89b20a0f8741f81f0729686e94e /tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp | |
parent | a7518a11b6975e1fb1ad8584fd4f5fa6b434d839 (diff) |
Avoid races on TZ in environment via tzset() calls
POSIX specifies that tzset() consults environment variable TZ and
modifies some globals; it also specifies mktime(), localtime() and
strftime() to behave as if they called tzset(). Fortunately, we only
call strftime() from a test and only call localtime() when not
threaded. Provide wrappers for tzset() and mktime() that share the
lock used by our environment-access code, to prevent races on the
environment (and tzset()'s globals) when we call them.
In the process, re-use tst_QDateTime's TimeZoneRollback in its older
test systemTimeZoneChange() and presume that this can now be tested
cross-platform, since TimeZoneRollback is used in another test where
this works.
Fixes: QTBUG-71030
Change-Id: I79f559b8857ea2803e73501008bf0d7158c6731f
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp')
-rw-r--r-- | tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp | 40 |
1 files changed, 7 insertions, 33 deletions
diff --git a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp index 943805e228..56792f38fb 100644 --- a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp +++ b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp @@ -37,9 +37,6 @@ #ifdef Q_OS_WIN # include <qt_windows.h> -# if defined(Q_OS_WINRT) -# define tzset() -# endif #endif class tst_QDateTime : public QObject @@ -145,9 +142,7 @@ private slots: void isDaylightTime() const; void daylightTransitions() const; void timeZones() const; -#if defined(Q_OS_UNIX) void systemTimeZoneChange() const; -#endif void invalid() const; @@ -174,7 +169,7 @@ private: void reset(const QByteArray &zone) { qputenv("TZ", zone.constData()); - tzset(); + qTzSet(); } ~TimeZoneRollback() { @@ -182,7 +177,7 @@ private: qunsetenv("TZ"); else qputenv("TZ", prior.constData()); - tzset(); + qTzSet(); } }; }; @@ -3412,33 +3407,10 @@ void tst_QDateTime::timeZones() const QCOMPARE(future.offsetFromUtc(), 28800); } -#if defined(Q_OS_UNIX) -// Currently disabled on Windows as adjusting the timezone -// requires additional privileges that aren't normally -// enabled for a process. This can be achieved by calling -// AdjustTokenPrivileges() and then SetTimeZoneInformation(), -// which will require linking to a different library to access that API. -static void setTimeZone(const QByteArray &tz) -{ - qputenv("TZ", tz); - ::tzset(); - -// following left for future reference, see comment above -// #if defined(Q_OS_WIN32) -// ::_tzset(); -// #endif -} - void tst_QDateTime::systemTimeZoneChange() const { - struct ResetTZ { - QByteArray original; - ResetTZ() : original(qgetenv("TZ")) {} - ~ResetTZ() { setTimeZone(original); } - } scopedReset; - // Set the timezone to Brisbane time - setTimeZone(QByteArray("AEST-10:00")); + TimeZoneRollback useZone(QByteArray("AEST-10:00")); QDateTime localDate = QDateTime(QDate(2012, 6, 1), QTime(2, 15, 30), Qt::LocalTime); QDateTime utcDate = QDateTime(QDate(2012, 6, 1), QTime(2, 15, 30), Qt::UTC); @@ -3451,16 +3423,18 @@ void tst_QDateTime::systemTimeZoneChange() const QVERIFY(tzDate.timeZone().isValid()); // Change to Indian time - setTimeZone(QByteArray("IST-05:30")); + useZone.reset(QByteArray("IST-05:30")); QCOMPARE(localDate, QDateTime(QDate(2012, 6, 1), QTime(2, 15, 30), Qt::LocalTime)); +#ifdef Q_OS_WINRT + QEXPECT_FAIL("", "WinRT gets this wrong, QTBUG-71185", Continue); +#endif QVERIFY(localMsecs != localDate.toMSecsSinceEpoch()); QCOMPARE(utcDate, QDateTime(QDate(2012, 6, 1), QTime(2, 15, 30), Qt::UTC)); QCOMPARE(utcDate.toMSecsSinceEpoch(), utcMsecs); QCOMPARE(tzDate, QDateTime(QDate(2012, 6, 1), QTime(2, 15, 30), QTimeZone("Australia/Brisbane"))); QCOMPARE(tzDate.toMSecsSinceEpoch(), tzMsecs); } -#endif void tst_QDateTime::invalid() const { |