| Index: chrome/browser/safe_browsing/bloom_filter.cc
|
| diff --git a/chrome/browser/safe_browsing/bloom_filter.cc b/chrome/browser/safe_browsing/bloom_filter.cc
|
| index 859d32011dabfd1a94857fcb2faca3bb4a382808..747a86f62b1715d36b3e76c726a4bf2fe0a1faba 100644
|
| --- a/chrome/browser/safe_browsing/bloom_filter.cc
|
| +++ b/chrome/browser/safe_browsing/bloom_filter.cc
|
| @@ -30,6 +30,24 @@ uint32 HashMix(BloomFilter::HashKey hash_key, uint32 c) {
|
| return c;
|
| }
|
|
|
| +uint32 CalculateChecksum(const char* data, size_t size,
|
| + const BloomFilter::HashKeys& keys) {
|
| + uint32 checksum = 0;
|
| + for (size_t i = 0; i < keys.size(); ++i) {
|
| + checksum ^= static_cast<uint32>(keys[i]);
|
| + checksum ^= static_cast<uint32>(keys[i]>>32);
|
| + }
|
| +
|
| + // Watch out for sign-extension in the calculation.
|
| + // TODO(shess): Bit manipulation of signed chars is insane.
|
| + const unsigned char* udata = reinterpret_cast<const unsigned char*>(data);
|
| + for (size_t i = 0; i < size; ++i) {
|
| + checksum ^= udata[i] << ((i * 8) % 32);
|
| + }
|
| +
|
| + return checksum;
|
| +}
|
| +
|
| } // namespace
|
|
|
| // static
|
| @@ -56,6 +74,7 @@ BloomFilter::BloomFilter(int bit_size) {
|
| DCHECK_LE(bit_size, bit_size_); // strictly more bits.
|
| data_.reset(new char[byte_size_]);
|
| memset(data_.get(), 0, byte_size_);
|
| + checksum_ = CalculateChecksum(data_.get(), 0, hash_keys_);
|
| }
|
|
|
| BloomFilter::BloomFilter(char* data, int size, const HashKeys& keys)
|
| @@ -63,6 +82,7 @@ BloomFilter::BloomFilter(char* data, int size, const HashKeys& keys)
|
| byte_size_ = size;
|
| bit_size_ = byte_size_ * 8;
|
| data_.reset(data);
|
| + checksum_ = CalculateChecksum(data_.get(), byte_size_, hash_keys_);
|
| }
|
|
|
| BloomFilter::~BloomFilter() {
|
| @@ -72,7 +92,12 @@ void BloomFilter::Insert(SBPrefix hash) {
|
| uint32 hash_uint32 = static_cast<uint32>(hash);
|
| for (size_t i = 0; i < hash_keys_.size(); ++i) {
|
| uint32 index = HashMix(hash_keys_[i], hash_uint32) % bit_size_;
|
| - data_[index / 8] |= 1 << (index % 8);
|
| + // Checksum needs to track the transition. Remove the if() when
|
| + // the checksum goes away.
|
| + if (!(data_[index / 8] & (1 << (index % 8)))) {
|
| + data_[index / 8] |= 1 << (index % 8);
|
| + checksum_ ^= 1u << (index % 32);
|
| + }
|
| }
|
| }
|
|
|
| @@ -190,3 +215,9 @@ bool BloomFilter::WriteFile(const FilePath& filter_name) const {
|
|
|
| return true;
|
| }
|
| +
|
| +bool BloomFilter::CheckChecksum() const {
|
| + const uint32 checksum = CalculateChecksum(data_.get(), byte_size_,
|
| + hash_keys_);
|
| + return checksum_ == checksum;
|
| +}
|
|
|