From 2ef8b92ececbf9d33d7c0b44f46c7c975fb0fdaa Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Thu, 8 Jul 2010 08:42:27 +0200 Subject: QUUid::createUuid() should not generate identical sequences on UNIX An unintended side-effect of commit 90a082c9076f35dcca092ade019891e92692710e is that if qrand() is used without being seeded first, then createUuid() would always generate the same sequence. This quite likely to happen considering the Qt does not actually seed the PRNG, but does use it in many places (we do not call qsrand(), but we do often call qrand()). Fix this by changing qrand() to calculate a seed, instead of defaulting to 1. This allows us to remove the qsrand() overload with no arguments, since qrand() will now seed automatically unless manually seeded by the programmer. Task-number: QTBUG-11213 Reviewed-by: thiago --- src/corelib/global/qglobal.cpp | 58 ++++++------------------------------------ src/corelib/plugin/quuid.cpp | 12 +++------ 2 files changed, 12 insertions(+), 58 deletions(-) diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 66519be..b24ba38 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -2586,55 +2586,6 @@ void qsrand(uint seed) #endif } -/*! \internal - \relates - \since 4.6 - - Seed the PRNG, but only if it has not already been seeded. - - The default seed is a combination of current time, a stack address and a - serial counter (since thread stack addresses are re-used). -*/ -void qsrand() -{ -#if (defined(Q_OS_UNIX) || defined(Q_OS_WIN)) && !defined(QT_NO_THREAD) - SeedStorage *seedStorage = randTLS(); - if (seedStorage) { - SeedStorageType *pseed = seedStorage->localData(); - if (pseed) { - // already seeded - return; - } - seedStorage->setLocalData(pseed = new SeedStorageType); - // start beyond 1 to avoid the sequence reset - static QBasicAtomicInt serial = Q_BASIC_ATOMIC_INITIALIZER(2); - *pseed = QDateTime::currentDateTime().toTime_t() - + quintptr(&pseed) - + serial.fetchAndAddRelaxed(1); -#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) - // for Windows and Symbian the srand function must still be called. - srand(*pseed); -#endif - } - -//QT_NO_THREAD implementations -#else - static unsigned int seed = 0; - - if (seed) - return; - -#if defined(Q_OS_SYMBIAN) - seed = Math::Random(); -#elif defined(Q_OS_WIN) - seed = GetTickCount(); -#else - seed = quintptr(&seed) + QDateTime::currentDateTime().toTime_t(); -#endif - srand(seed); -#endif // defined(Q_OS_UNIX) || defined(Q_OS_WIN)) && !defined(QT_NO_THREAD) -} - /*! \relates \since 4.2 @@ -2658,7 +2609,14 @@ int qrand() SeedStorageType *pseed = seedStorage->localData(); if (!pseed) { seedStorage->setLocalData(pseed = new SeedStorageType); - *pseed = 1; + + // Seed the PRNG, but only if it has not already been seeded. The + // default seed is a combination of current time, a stack address + // and a serial counter (since thread stack addresses are re-used). + static QBasicAtomicInt serial = Q_BASIC_ATOMIC_INITIALIZER(2); + *pseed = QDateTime::currentDateTime().toTime_t() + + quintptr(&pseed) + + serial.fetchAndAddRelaxed(1); } return rand_r(pseed); } else { diff --git a/src/corelib/plugin/quuid.cpp b/src/corelib/plugin/quuid.cpp index 8541c7d..6a7d35c 100644 --- a/src/corelib/plugin/quuid.cpp +++ b/src/corelib/plugin/quuid.cpp @@ -577,23 +577,19 @@ QUuid QUuid::createUuid() QT_BEGIN_INCLUDE_NAMESPACE #include "qdatetime.h" -#include "stdlib.h" // For srand/rand QT_END_INCLUDE_NAMESPACE -extern void qsrand(); // in qglobal.cpp - QUuid QUuid::createUuid() { static const int intbits = sizeof(int)*8; static int randbits = 0; if (!randbits) { + int r = 0; int max = RAND_MAX; - do { ++randbits; } while ((max=max>>1)); + do { ++r; } while ((max=max>>1)); + randbits = r; } - // reseed, but only if not already seeded - qsrand(); - QUuid result; uint *data = &(result.data1); int chunks = 16 / sizeof(uint); @@ -601,7 +597,7 @@ QUuid QUuid::createUuid() uint randNumber = 0; for (int filled = 0; filled < intbits; filled += randbits) randNumber |= qrand()< Date: Thu, 8 Jul 2010 11:47:09 +0200 Subject: Compile Re-add the stdlib.h include, since it brings in RAND_MAX Reviewed-by: TrustMe --- src/corelib/plugin/quuid.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/corelib/plugin/quuid.cpp b/src/corelib/plugin/quuid.cpp index 6a7d35c..f48cc2e 100644 --- a/src/corelib/plugin/quuid.cpp +++ b/src/corelib/plugin/quuid.cpp @@ -577,6 +577,7 @@ QUuid QUuid::createUuid() QT_BEGIN_INCLUDE_NAMESPACE #include "qdatetime.h" +#include // for RAND_MAX QT_END_INCLUDE_NAMESPACE QUuid QUuid::createUuid() -- cgit v0.12 From c48eb6d5d0a299449330dea8a6a59514942c8781 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Thu, 8 Jul 2010 15:27:14 +0200 Subject: Initalize the nativeDialogInUse variable When the variable was not initalized it would randomly show a native font dialog or a non native one if the DontUseNativeDialogs flag was set. Task-number: QTBUG-12042 Reviewed-by: cduclos --- src/gui/dialogs/qfontdialog.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/dialogs/qfontdialog.cpp b/src/gui/dialogs/qfontdialog.cpp index a4bf15d..e9e3f23 100644 --- a/src/gui/dialogs/qfontdialog.cpp +++ b/src/gui/dialogs/qfontdialog.cpp @@ -332,6 +332,7 @@ void QFontDialogPrivate::init() #ifdef Q_WS_MAC delegate = 0; + nativeDialogInUse = false; #endif } -- cgit v0.12