diff options
-rw-r--r-- | src/corelib/plugin/quuid.cpp | 98 | ||||
-rw-r--r-- | src/corelib/plugin/quuid.h | 1 | ||||
-rw-r--r-- | src/corelib/tools/qhash.cpp | 40 | ||||
-rw-r--r-- | src/network/access/qhttpmultipart.cpp | 21 |
4 files changed, 20 insertions, 140 deletions
diff --git a/src/corelib/plugin/quuid.cpp b/src/corelib/plugin/quuid.cpp index c9644c73d3..11ef247531 100644 --- a/src/corelib/plugin/quuid.cpp +++ b/src/corelib/plugin/quuid.cpp @@ -40,14 +40,13 @@ #include "quuid.h" +#include "qcryptographichash.h" #include "qdatastream.h" -#include "qendian.h" #include "qdebug.h" +#include "qendian.h" +#include "qrandom.h" #include "private/qtools_p.h" -#ifndef QT_BOOTSTRAPPED -#include "qcryptographichash.h" -#endif QT_BEGIN_NAMESPACE // 16 bytes (a uint, two shorts and a uchar[8]), each represented by two hex @@ -918,17 +917,10 @@ bool QUuid::operator>(const QUuid &other) const Q_DECL_NOTHROW /*! \fn QUuid QUuid::createUuid() - On any platform other than Windows, this function returns a new - UUID with variant QUuid::DCE and version QUuid::Random. If - the /dev/urandom device exists, then the numbers used to construct - the UUID will be of cryptographic quality, which will make the UUID - unique. Otherwise, the numbers of the UUID will be obtained from - the local pseudo-random number generator (qrand(), which is seeded - by qsrand()) which is usually not of cryptograhic quality, which - means that the UUID can't be guaranteed to be unique. - - On a Windows platform, a GUID is generated, which almost certainly - \e{will} be unique, on this or any other system, networked or not. + On any platform other than Windows, this function returns a new UUID with + variant QUuid::DCE and version QUuid::Random. On Windows, a GUID is + generated using the Windows API and will be of the type that the API + decides to create. \sa variant(), version() */ @@ -948,82 +940,12 @@ QUuid QUuid::createUuid() #else // Q_OS_WIN -QT_BEGIN_INCLUDE_NAMESPACE -#include "qdatetime.h" -#include "qfile.h" -#include "qthreadstorage.h" -#include <stdlib.h> // for RAND_MAX -QT_END_INCLUDE_NAMESPACE - -#if !defined(QT_BOOTSTRAPPED) && defined(Q_OS_UNIX) -Q_GLOBAL_STATIC(QThreadStorage<QFile *>, devUrandomStorage); -#endif - QUuid QUuid::createUuid() { - QUuid result; + QUuid result(Qt::Uninitialized); uint *data = &(result.data1); - -#if defined(Q_OS_UNIX) - QFile *devUrandom; -# if !defined(QT_BOOTSTRAPPED) - devUrandom = devUrandomStorage()->localData(); - if (!devUrandom) { - devUrandom = new QFile(QLatin1String("/dev/urandom")); - devUrandom->open(QIODevice::ReadOnly | QIODevice::Unbuffered); - devUrandomStorage()->setLocalData(devUrandom); - } -# else - QFile file(QLatin1String("/dev/urandom")); - devUrandom = &file; - devUrandom->open(QIODevice::ReadOnly | QIODevice::Unbuffered); -# endif - enum { AmountToRead = 4 * sizeof(uint) }; - if (devUrandom->isOpen() - && devUrandom->read((char *) data, AmountToRead) == AmountToRead) { - // we got what we wanted, nothing more to do - ; - } else -#endif - { - static const int intbits = sizeof(int)*8; - static int randbits = 0; - if (!randbits) { - int r = 0; - int max = RAND_MAX; - do { ++r; } while ((max=max>>1)); - randbits = r; - } - - // Seed the PRNG once per thread with a combination of current time, a - // stack address and a serial counter (since thread stack addresses are - // re-used). -#ifndef QT_BOOTSTRAPPED - static QThreadStorage<int *> uuidseed; - if (!uuidseed.hasLocalData()) - { - int *pseed = new int; - static QBasicAtomicInt serial = Q_BASIC_ATOMIC_INITIALIZER(0); - qsrand(*pseed = QDateTime::currentSecsSinceEpoch() - + quintptr(&pseed) - + 2 + serial.fetchAndAddRelaxed(1)); - uuidseed.setLocalData(pseed); - } -#else - static bool seeded = false; - if (!seeded) - qsrand(QDateTime::currentSecsSinceEpoch() - + quintptr(&seeded)); -#endif - - int chunks = 16 / sizeof(uint); - while (chunks--) { - uint randNumber = 0; - for (int filled = 0; filled < intbits; filled += randbits) - randNumber |= qrand()<<filled; - *(data+chunks) = randNumber; - } - } + enum { AmountToRead = 4 }; + QRandomGenerator::fillRange(data, AmountToRead); result.data4[0] = (result.data4[0] & 0x3F) | 0x80; // UV_DCE result.data3 = (result.data3 & 0x0FFF) | 0x4000; // UV_Random diff --git a/src/corelib/plugin/quuid.h b/src/corelib/plugin/quuid.h index d975528dcf..9e1a35f492 100644 --- a/src/corelib/plugin/quuid.h +++ b/src/corelib/plugin/quuid.h @@ -65,6 +65,7 @@ QT_BEGIN_NAMESPACE class Q_CORE_EXPORT QUuid { + QUuid(Qt::Initialization) {} public: enum Variant { VarUnknown =-1, diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp index 59aab32347..9d8c276cff 100644 --- a/src/corelib/tools/qhash.cpp +++ b/src/corelib/tools/qhash.cpp @@ -63,13 +63,9 @@ #ifndef QT_BOOTSTRAPPED #include <qcoreapplication.h> +#include <qrandom.h> #endif // QT_BOOTSTRAPPED -#ifdef Q_OS_UNIX -#include <stdio.h> -#include "private/qcore_unix_p.h" -#endif // Q_OS_UNIX - #include <limits.h> QT_BEGIN_NAMESPACE @@ -298,39 +294,7 @@ static uint qt_create_qhash_seed() return seed; } -#ifdef Q_OS_UNIX - int randomfd = qt_safe_open("/dev/urandom", O_RDONLY); - if (randomfd == -1) - randomfd = qt_safe_open("/dev/random", O_RDONLY | O_NONBLOCK); - if (randomfd != -1) { - if (qt_safe_read(randomfd, reinterpret_cast<char *>(&seed), sizeof(seed)) == sizeof(seed)) { - qt_safe_close(randomfd); - return seed; - } - qt_safe_close(randomfd); - } -#endif // Q_OS_UNIX - -#if defined(Q_OS_WIN32) && !defined(Q_CC_GNU) - errno_t err; - err = rand_s(&seed); - if (err == 0) - return seed; -#endif // Q_OS_WIN32 - - // general fallback: initialize from the current timestamp, pid, - // and address of a stack-local variable - quint64 timestamp = QDateTime::currentMSecsSinceEpoch(); - seed ^= timestamp; - seed ^= (timestamp >> 32); - - quint64 pid = QCoreApplication::applicationPid(); - seed ^= pid; - seed ^= (pid >> 32); - - quintptr seedPtr = reinterpret_cast<quintptr>(&seed); - seed ^= seedPtr; - seed ^= (qulonglong(seedPtr) >> 32); // no-op on 32-bit platforms + seed = QRandomGenerator::get32(); #endif // QT_BOOTSTRAPPED return seed; diff --git a/src/network/access/qhttpmultipart.cpp b/src/network/access/qhttpmultipart.cpp index 5c704efeef..303c145394 100644 --- a/src/network/access/qhttpmultipart.cpp +++ b/src/network/access/qhttpmultipart.cpp @@ -41,7 +41,7 @@ #include "qhttpmultipart_p.h" #include "QtCore/qdatetime.h" // for initializing the random number generator with QTime #include "QtCore/qmutex.h" -#include "QtCore/qthreadstorage.h" +#include "QtCore/qrandom.h" QT_BEGIN_NAMESPACE @@ -431,23 +431,16 @@ void QHttpPartPrivate::checkHeaderCreated() const } } -Q_GLOBAL_STATIC(QThreadStorage<bool *>, seedCreatedStorage); - QHttpMultiPartPrivate::QHttpMultiPartPrivate() : contentType(QHttpMultiPart::MixedType), device(new QHttpMultiPartIODevice(this)) { - if (!seedCreatedStorage()->hasLocalData()) { - qsrand(QTime(0,0,0).msecsTo(QTime::currentTime()) ^ reinterpret_cast<quintptr>(this)); - seedCreatedStorage()->setLocalData(new bool(true)); - } - - boundary = QByteArray("boundary_.oOo._") - + QByteArray::number(qrand()).toBase64() - + QByteArray::number(qrand()).toBase64() - + QByteArray::number(qrand()).toBase64(); + // 24 random bytes, becomes 32 characters when encoded to Base64 + quint32 random[6]; + QRandomGenerator::fillRange(random); + boundary = "boundary_.oOo._" + + QByteArray::fromRawData(reinterpret_cast<char *>(random), sizeof(random)).toBase64(); // boundary must not be longer than 70 characters, see RFC 2046, section 5.1.1 - if (boundary.count() > 70) - boundary = boundary.left(70); + Q_ASSERT(boundary.count() <= 70); } qint64 QHttpMultiPartIODevice::size() const |