diff options
author | Justin Seyster <justin.seyster@mongodb.com> | 2019-04-15 16:35:48 -0400 |
---|---|---|
committer | Justin Seyster <justin.seyster@mongodb.com> | 2019-04-15 16:49:42 -0400 |
commit | ec5473699c86897dc98fca6aac63eb92dcbcc1c4 (patch) | |
tree | bd3319fdfdffad15cd64600a6d7e1a289bcf9931 /src/mongo/db/hasher.cpp | |
parent | 195271e1c8254f26636331b9e07067e2eab16374 (diff) | |
download | mongo-ec5473699c86897dc98fca6aac63eb92dcbcc1c4.tar.gz |
SERVER-40513 Convert seed to little endian before hashing
Diffstat (limited to 'src/mongo/db/hasher.cpp')
-rw-r--r-- | src/mongo/db/hasher.cpp | 28 |
1 files changed, 24 insertions, 4 deletions
diff --git a/src/mongo/db/hasher.cpp b/src/mongo/db/hasher.cpp index 731500afa40..677d34d9b7f 100644 --- a/src/mongo/db/hasher.cpp +++ b/src/mongo/db/hasher.cpp @@ -57,24 +57,45 @@ public: // pointer to next part of input key, length in bytes to read void addData(const void* keyData, size_t numBytes); + void addSeed(int32_t number) { + addIntegerData(number); + } + + // All numerical values should be converted to an int64_t before being added to the hash input. + void addNumber(int64_t number) { + addIntegerData(number); + } + // finish computing the hash, put the result in the digest // only call this once per Hasher void finish(HashDigest out); private: + // Convert 'number' to little endian and then append it to the digest input. The number of bytes + // appended is determined by the input type, so ensure that type T has a well defined size that + // is the same on all platforms. + template <typename T> + void addIntegerData(T number); + md5_state_t _md5State; HashSeed _seed; }; Hasher::Hasher(HashSeed seed) : _seed(seed) { md5_init(&_md5State); - md5_append(&_md5State, reinterpret_cast<const md5_byte_t*>(&_seed), sizeof(_seed)); + addSeed(seed); } void Hasher::addData(const void* keyData, size_t numBytes) { md5_append(&_md5State, static_cast<const md5_byte_t*>(keyData), numBytes); } +template <typename T> +void Hasher::addIntegerData(T number) { + const auto data = endian::nativeToLittle(number); + addData(&data, sizeof(data)); +} + void Hasher::finish(HashDigest out) { md5_finish(&_md5State, out); } @@ -91,9 +112,8 @@ void recursiveHash(Hasher* h, const BSONElement& e, bool includeFieldName) { // if there are no embedded objects (subobjects or arrays), // compute the hash, squashing numeric types to 64-bit ints if (e.isNumber()) { - // Use safeNumberLongForHash, it is well-defined for troublesome doubles. - const auto i = endian::nativeToLittle(e.safeNumberLongForHash()); - h->addData(&i, sizeof(i)); + // Use safeNumberLongForHash, because it is well-defined for troublesome doubles. + h->addNumber(static_cast<int64_t>(e.safeNumberLongForHash())); } else { h->addData(e.value(), e.valuesize()); } |