| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/safe_browsing/prefix_set.h" | 5 #include "chrome/browser/safe_browsing/prefix_set.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <math.h> | 8 #include <math.h> |
| 9 | 9 |
| 10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 static uint32 kMagic = 0x864088dd; | 22 static uint32 kMagic = 0x864088dd; |
| 23 | 23 |
| 24 // Version history: | 24 // Version history: |
| 25 // Version 1: b6cb7cfe/r74487 by shess@chromium.org on 2011-02-10 | 25 // Version 1: b6cb7cfe/r74487 by shess@chromium.org on 2011-02-10 |
| 26 // Version 2: 2b59b0a6/r253924 by shess@chromium.org on 2014-02-27 | 26 // Version 2: 2b59b0a6/r253924 by shess@chromium.org on 2014-02-27 |
| 27 // Version 3: ????????/r?????? by shess@chromium.org on 2014-04-?? | 27 // Version 3: ????????/r?????? by shess@chromium.org on 2014-04-?? |
| 28 | 28 |
| 29 // Version 2 layout is identical to version 1. The sort order of |index_| | 29 // Version 2 layout is identical to version 1. The sort order of |index_| |
| 30 // changed from |int32| to |uint32| to match the change of |SBPrefix|. | 30 // changed from |int32| to |uint32| to match the change of |SBPrefix|. |
| 31 // Version 3 adds storage for full hashes. | 31 // Version 3 adds storage for full hashes. |
| 32 static uint32 kVersion = 0x3; | 32 static uint32 kVersion = 3; |
| 33 static uint32 kDeprecatedVersion = 1; // And lower. |
| 33 | 34 |
| 34 typedef struct { | 35 typedef struct { |
| 35 uint32 magic; | 36 uint32 magic; |
| 36 uint32 version; | 37 uint32 version; |
| 37 uint32 index_size; | 38 uint32 index_size; |
| 38 uint32 deltas_size; | 39 uint32 deltas_size; |
| 39 } FileHeader_v2; | 40 } FileHeader_v2; |
| 40 | 41 |
| 41 typedef struct { | 42 typedef struct { |
| 42 uint32 magic; | 43 uint32 magic; |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 188 base::MD5Init(&context); | 189 base::MD5Init(&context); |
| 189 base::MD5Update(&context, base::StringPiece(reinterpret_cast<char*>(&header), | 190 base::MD5Update(&context, base::StringPiece(reinterpret_cast<char*>(&header), |
| 190 sizeof(header))); | 191 sizeof(header))); |
| 191 | 192 |
| 192 if (header.magic != kMagic) | 193 if (header.magic != kMagic) |
| 193 return scoped_ptr<PrefixSet>(); | 194 return scoped_ptr<PrefixSet>(); |
| 194 | 195 |
| 195 // Track version read to inform removal of support for older versions. | 196 // Track version read to inform removal of support for older versions. |
| 196 UMA_HISTOGRAM_SPARSE_SLOWLY("SB2.PrefixSetVersionRead", header.version); | 197 UMA_HISTOGRAM_SPARSE_SLOWLY("SB2.PrefixSetVersionRead", header.version); |
| 197 | 198 |
| 198 // TODO(shess): Version 1 and 2 use the same file structure, with version 1 | |
| 199 // data using a signed sort. For M-35, the data is re-sorted before return. | |
| 200 // After M-36, just drop v1 support. <http://crbug.com/346405> | |
| 201 // TODO(shess): <http://crbug.com/368044> for removing v2 support. | 199 // TODO(shess): <http://crbug.com/368044> for removing v2 support. |
| 202 size_t header_size = sizeof(header); | 200 size_t header_size = sizeof(header); |
| 203 if (header.version == 2 || header.version == 1) { | 201 if (header.version <= kDeprecatedVersion) { |
| 202 return scoped_ptr<PrefixSet>(); |
| 203 } else if (header.version == 2) { |
| 204 // Rewind the file and restart building the digest with the old header | 204 // Rewind the file and restart building the digest with the old header |
| 205 // structure. | 205 // structure. |
| 206 FileHeader_v2 v2_header; | 206 FileHeader_v2 v2_header; |
| 207 if (0 != fseek(file.get(), 0, SEEK_SET)) | 207 if (0 != fseek(file.get(), 0, SEEK_SET)) |
| 208 return scoped_ptr<PrefixSet>(); | 208 return scoped_ptr<PrefixSet>(); |
| 209 | 209 |
| 210 size_t read = fread(&v2_header, sizeof(v2_header), 1, file.get()); | 210 size_t read = fread(&v2_header, sizeof(v2_header), 1, file.get()); |
| 211 if (read != 1) | 211 if (read != 1) |
| 212 return scoped_ptr<PrefixSet>(); | 212 return scoped_ptr<PrefixSet>(); |
| 213 | 213 |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 285 base::MD5Final(&calculated_digest, &context); | 285 base::MD5Final(&calculated_digest, &context); |
| 286 | 286 |
| 287 base::MD5Digest file_digest; | 287 base::MD5Digest file_digest; |
| 288 read = fread(&file_digest, sizeof(file_digest), 1, file.get()); | 288 read = fread(&file_digest, sizeof(file_digest), 1, file.get()); |
| 289 if (read != 1) | 289 if (read != 1) |
| 290 return scoped_ptr<PrefixSet>(); | 290 return scoped_ptr<PrefixSet>(); |
| 291 | 291 |
| 292 if (0 != memcmp(&file_digest, &calculated_digest, sizeof(file_digest))) | 292 if (0 != memcmp(&file_digest, &calculated_digest, sizeof(file_digest))) |
| 293 return scoped_ptr<PrefixSet>(); | 293 return scoped_ptr<PrefixSet>(); |
| 294 | 294 |
| 295 // For version 1, fetch the prefixes and re-sort. | |
| 296 if (header.version == 1) { | |
| 297 std::vector<SBPrefix> prefixes; | |
| 298 PrefixSet(&index, &deltas, &full_hashes).GetPrefixes(&prefixes); | |
| 299 std::sort(prefixes.begin(), prefixes.end()); | |
| 300 | |
| 301 // v1 cannot have full hashes, so no need to propagate a copy here. | |
| 302 return PrefixSetBuilder(prefixes).GetPrefixSetNoHashes().Pass(); | |
| 303 } | |
| 304 | |
| 305 // Steals vector contents using swap(). | 295 // Steals vector contents using swap(). |
| 306 return scoped_ptr<PrefixSet>(new PrefixSet(&index, &deltas, &full_hashes)); | 296 return scoped_ptr<PrefixSet>(new PrefixSet(&index, &deltas, &full_hashes)); |
| 307 } | 297 } |
| 308 | 298 |
| 309 bool PrefixSet::WriteFile(const base::FilePath& filter_name) const { | 299 bool PrefixSet::WriteFile(const base::FilePath& filter_name) const { |
| 310 FileHeader header; | 300 FileHeader header; |
| 311 header.magic = kMagic; | 301 header.magic = kMagic; |
| 312 header.version = kVersion; | 302 header.version = kVersion; |
| 313 header.index_size = static_cast<uint32>(index_.size()); | 303 header.index_size = static_cast<uint32>(index_.size()); |
| 314 header.deltas_size = static_cast<uint32>(deltas_.size()); | 304 header.deltas_size = static_cast<uint32>(deltas_.size()); |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 483 } | 473 } |
| 484 buffer_.push_back(prefix); | 474 buffer_.push_back(prefix); |
| 485 | 475 |
| 486 // Flush buffer when a run can be constructed. +1 for the index item, and +1 | 476 // Flush buffer when a run can be constructed. +1 for the index item, and +1 |
| 487 // to leave at least one item in the buffer for dropping duplicates. | 477 // to leave at least one item in the buffer for dropping duplicates. |
| 488 if (buffer_.size() > PrefixSet::kMaxRun + 2) | 478 if (buffer_.size() > PrefixSet::kMaxRun + 2) |
| 489 EmitRun(); | 479 EmitRun(); |
| 490 } | 480 } |
| 491 | 481 |
| 492 } // namespace safe_browsing | 482 } // namespace safe_browsing |
| OLD | NEW |