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 |