summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGabriel de Dietrich <gabriel.dedietrich@theqtcompany.com>2015-09-21 15:53:49 +0200
committerGabriel de Dietrich <gabriel.dedietrich@theqtcompany.com>2015-09-22 14:17:46 +0000
commita14fadfb640103ecea76c3966cf23668bb7f448b (patch)
treea8a9de3fca0070109066085e3c467ec21534129f /src
parent863dfb1541f4f0865a6e4ee42dbef159eaa7f2d0 (diff)
Add getter and setter for qt_qhash_seed
In some cases it's not possible to use QT_HASH_SEED, specially when we need to set the environment variable from inside the application, as dynamically loaded libraries or plugins may create static QHash instances. That would set qt_qhash_seed to a value different from -1 and skip the env var value. For those cases, and when we still want to set qt_qhash_seed, we provide a way to enforce its value. Auto-tests accessing qt_qhash_seed directly have been updated accordingly. Usage in qdoc, uic and rcc has been left as is for the time being. Change-Id: I3b35b4fa0223c83b1348a6508641905a2a63266f Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/tools/qhash.cpp50
-rw-r--r--src/corelib/tools/qhash.h3
2 files changed, 52 insertions, 1 deletions
diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp
index 1f3ea36121..b334a697a9 100644
--- a/src/corelib/tools/qhash.cpp
+++ b/src/corelib/tools/qhash.cpp
@@ -290,6 +290,53 @@ static void qt_initialize_qhash_seed()
}
}
+/*! \relates QHash
+ \since 5.6
+
+ Returns the current global QHash seed.
+
+ The seed is set in any newly created QHash. See \l{qHash} about how this seed
+ is being used by QHash.
+
+ \sa qSetGlobalQHashSeed
+ */
+int qGlobalQHashSeed()
+{
+ return qt_qhash_seed.load();
+}
+
+/*! \relates QHash
+ \since 5.6
+
+ Sets the global QHash seed.
+
+ Manually setting the global QHash seed value should be done only for testing
+ and debugging purposes, when deterministic and reproducible behavior on a QHash
+ is needed. We discourage to do it in production code as it can make your
+ application susceptible to \l{algorithmic complexity attacks}.
+
+ The seed is set in any newly created QHash. See \l{qHash} about how this seed
+ is being used by QHash.
+
+ If the environment variable \c QT_HASH_SEED is set, calling this function will
+ result in a no-op.
+
+ Passing the value -1 will reinitialize the global QHash seed to a random value.
+
+ \sa qGlobalQHashSeed
+ */
+void qSetGlobalQHashSeed(int newSeed)
+{
+ if (qEnvironmentVariableIsSet("QT_HASH_SEED"))
+ return;
+ if (newSeed == -1) {
+ int x(qt_create_qhash_seed() & INT_MAX);
+ qt_qhash_seed.store(x);
+ } else {
+ qt_qhash_seed.store(newSeed & INT_MAX);
+ }
+}
+
/*!
\internal
@@ -1132,7 +1179,8 @@ uint qHash(long double key, uint seed) Q_DECL_NOTHROW
where you temporarily need deterministic behavior, for example for debugging or
regression testing. To disable the randomization, define the environment
variable \c QT_HASH_SEED. The contents of that variable, interpreted as a
- decimal value, will be used as the seed for qHash().
+ decimal value, will be used as the seed for qHash(). Alternatively, you can
+ call the qSetGlobalQHashSeed() function.
\sa QHashIterator, QMutableHashIterator, QMap, QSet
*/
diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h
index e367cc0068..8d65a018ae 100644
--- a/src/corelib/tools/qhash.h
+++ b/src/corelib/tools/qhash.h
@@ -1037,6 +1037,9 @@ Q_INLINE_TEMPLATE int QMultiHash<Key, T>::count(const Key &key, const T &value)
return n;
}
+Q_CORE_EXPORT int qGlobalQHashSeed();
+Q_CORE_EXPORT void qSetGlobalQHashSeed(int newSeed);
+
Q_DECLARE_ASSOCIATIVE_ITERATOR(Hash)
Q_DECLARE_MUTABLE_ASSOCIATIVE_ITERATOR(Hash)