diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/io/qresource.cpp | 2 | ||||
-rw-r--r-- | src/corelib/io/qtldurl.cpp | 2 | ||||
-rw-r--r-- | src/corelib/tools/qhash.cpp | 30 | ||||
-rw-r--r-- | src/corelib/tools/qhash.h | 1 | ||||
-rw-r--r-- | src/tools/rcc/rcc.cpp | 4 |
5 files changed, 35 insertions, 4 deletions
diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp index fb3a24b940..4a0211c00a 100644 --- a/src/corelib/io/qresource.cpp +++ b/src/corelib/io/qresource.cpp @@ -673,7 +673,7 @@ int QResourceRoot::findNode(const QString &_path, const QLocale &locale) const qDebug() << " " << child+j << " :: " << name(child+j); } #endif - const uint h = qHash(segment); + const uint h = qt_hash(segment.toString()); //do the binary search for the hash int l = 0, r = child_count-1; diff --git a/src/corelib/io/qtldurl.cpp b/src/corelib/io/qtldurl.cpp index 48df01b48c..efd663b09a 100644 --- a/src/corelib/io/qtldurl.cpp +++ b/src/corelib/io/qtldurl.cpp @@ -50,7 +50,7 @@ QT_BEGIN_NAMESPACE static bool containsTLDEntry(const QString &entry) { - int index = qHash(entry) % tldCount; + int index = qt_hash(entry) % tldCount; int currentDomainIndex = tldIndices[index]; while (currentDomainIndex < tldIndices[index+1]) { QString currentEntry = QString::fromUtf8(tldData + currentDomainIndex); diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp index 6119c945fe..ce7d4ad098 100644 --- a/src/corelib/tools/qhash.cpp +++ b/src/corelib/tools/qhash.cpp @@ -222,6 +222,31 @@ static void qt_initialize_qhash_seed() } } +/*! + \internal + + Private copy of the implementation of the Qt 4 qHash algorithm for strings, + to be used wherever the result is somehow stored or reused across multiple + Qt versions. The public qHash implementation can change at any time, + therefore one must not rely on the fact that it will always give the same + results. + + This function must *never* change its results. +*/ +uint qt_hash(const QString &key) +{ + const QChar *p = key.unicode(); + int n = key.size(); + uint h = 0; + + while (n--) { + h = (h << 4) + (*p++).unicode(); + h ^= (h & 0xf0000000) >> 23; + h &= 0x0fffffff; + } + return h; +} + /* The prime_deltas array is a table of selected prime values, even though it doesn't look like one. The primes we are using are 1, @@ -817,6 +842,11 @@ void QHashData::checkSanity() XOR'ed this with the day they were born to help produce unique hashes for people with the same name. + Note that the implementation of the qHash() overloads offered by Qt + may change at any time. You \b{must not} rely on the fact that qHash() + will give the same results (for the same inputs) across different Qt + versions. + \section2 Algorithmic complexity attacks All hash tables are vulnerable to a particular class of denial of service diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h index 42c33f6f78..533208da85 100644 --- a/src/corelib/tools/qhash.h +++ b/src/corelib/tools/qhash.h @@ -89,6 +89,7 @@ Q_CORE_EXPORT uint qHash(const QString &key, uint seed = 0); Q_CORE_EXPORT uint qHash(const QStringRef &key, uint seed = 0); Q_CORE_EXPORT uint qHash(const QBitArray &key, uint seed = 0); Q_CORE_EXPORT uint qHash(const QLatin1String &key, uint seed = 0); +Q_CORE_EXPORT uint qt_hash(const QString &key); #if defined(Q_CC_MSVC) #pragma warning( push ) diff --git a/src/tools/rcc/rcc.cpp b/src/tools/rcc/rcc.cpp index 8a9afec690..46dec1d6ca 100644 --- a/src/tools/rcc/rcc.cpp +++ b/src/tools/rcc/rcc.cpp @@ -296,7 +296,7 @@ qint64 RCCFileInfo::writeDataName(RCCResourceLibrary &lib, qint64 offset) offset += 2; // write the hash - lib.writeNumber4(qHash(m_name)); + lib.writeNumber4(qt_hash(m_name)); if (text) lib.writeString("\n "); offset += 4; @@ -880,7 +880,7 @@ bool RCCResourceLibrary::writeDataNames() static bool qt_rcc_compare_hash(const RCCFileInfo *left, const RCCFileInfo *right) { - return qHash(left->m_name) < qHash(right->m_name); + return qt_hash(left->m_name) < qt_hash(right->m_name); } bool RCCResourceLibrary::writeDataStructure() |