aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/google/protobuf/descriptor.cc
diff options
context:
space:
mode:
authorGravatar Eugene Hermann <39246518+eughermann@users.noreply.github.com>2018-05-14 15:37:18 -0700
committerGravatar GitHub <noreply@github.com>2018-05-14 15:37:18 -0700
commit72d18e3faa7c04c6f6d4522338afbc57422df171 (patch)
tree911cb0a96ec936059c588efe84e81b0c542927b5 /src/google/protobuf/descriptor.cc
parentb61dd9d9a229c5a82788fdeefa344aa65affae09 (diff)
Remove undefined behavior from the hash function.
Signed integer overflow creates undefined behavior that may lead to unpredictable fails on different platforms. One known example of the hardware where this code did fail is Apple A6 (32-bit Apple Swift CPU) 16777619, 16777499 - two prime numbers that typically used to get better dispersion.
Diffstat (limited to 'src/google/protobuf/descriptor.cc')
-rw-r--r--src/google/protobuf/descriptor.cc14
1 files changed, 7 insertions, 7 deletions
diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc
index d466dd8b..dae24f9e 100644
--- a/src/google/protobuf/descriptor.cc
+++ b/src/google/protobuf/descriptor.cc
@@ -406,9 +406,10 @@ typedef std::pair<const EnumDescriptor*, int> EnumIntPair;
template<typename PairType>
struct PointerIntegerPairHash {
size_t operator()(const PairType& p) const {
- // FIXME(kenton): What is the best way to compute this hash? I have
- // no idea! This seems a bit better than an XOR.
- return reinterpret_cast<intptr_t>(p.first) * ((1 << 16) - 1) + p.second;
+ static const size_t prime1 = 16777499;
+ static const size_t prime2 = 16777619;
+ return reinterpret_cast<size_t>(p.first) * prime1 ^
+ static_cast<size_t>(p.second) * prime2;
}
#ifdef _MSC_VER
@@ -424,11 +425,10 @@ struct PointerIntegerPairHash {
struct PointerStringPairHash {
size_t operator()(const PointerStringPair& p) const {
- // FIXME(kenton): What is the best way to compute this hash? I have
- // no idea! This seems a bit better than an XOR.
+ static const size_t prime = 16777619;
hash<const char*> cstring_hash;
- return reinterpret_cast<intptr_t>(p.first) * ((1 << 16) - 1) +
- cstring_hash(p.second);
+ return reinterpret_cast<size_t>(p.first) * prime ^
+ static_cast<size_t>(cstring_hash(p.second));
}
#ifdef _MSC_VER