summaryrefslogtreecommitdiff
path: root/src/mongo/db/hasher.cpp
diff options
context:
space:
mode:
authorJustin Seyster <justin.seyster@mongodb.com>2019-04-15 16:35:48 -0400
committerJustin Seyster <justin.seyster@mongodb.com>2019-04-15 16:49:42 -0400
commitec5473699c86897dc98fca6aac63eb92dcbcc1c4 (patch)
treebd3319fdfdffad15cd64600a6d7e1a289bcf9931 /src/mongo/db/hasher.cpp
parent195271e1c8254f26636331b9e07067e2eab16374 (diff)
downloadmongo-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.cpp28
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());
}