| 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 <iterator> | 8 #include <iterator> |
| 9 | 9 |
| 10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 | 30 |
| 31 namespace safe_browsing { | 31 namespace safe_browsing { |
| 32 | 32 |
| 33 class PrefixSetTest : public PlatformTest { | 33 class PrefixSetTest : public PlatformTest { |
| 34 protected: | 34 protected: |
| 35 // Constants for the v1 format. | 35 // Constants for the v1 format. |
| 36 static const size_t kMagicOffset = 0 * sizeof(uint32); | 36 static const size_t kMagicOffset = 0 * sizeof(uint32); |
| 37 static const size_t kVersionOffset = 1 * sizeof(uint32); | 37 static const size_t kVersionOffset = 1 * sizeof(uint32); |
| 38 static const size_t kIndexSizeOffset = 2 * sizeof(uint32); | 38 static const size_t kIndexSizeOffset = 2 * sizeof(uint32); |
| 39 static const size_t kDeltasSizeOffset = 3 * sizeof(uint32); | 39 static const size_t kDeltasSizeOffset = 3 * sizeof(uint32); |
| 40 static const size_t kPayloadOffset = 4 * sizeof(uint32); | 40 static const size_t kFullHashesSizeOffset = 4 * sizeof(uint32); |
| 41 static const size_t kPayloadOffset = 5 * sizeof(uint32); |
| 41 | 42 |
| 42 // Generate a set of random prefixes to share between tests. For | 43 // Generate a set of random prefixes to share between tests. For |
| 43 // most tests this generation was a large fraction of the test time. | 44 // most tests this generation was a large fraction of the test time. |
| 44 // | 45 // |
| 45 // The set should contain sparse areas where adjacent items are more | 46 // The set should contain sparse areas where adjacent items are more |
| 46 // than 2^16 apart, and dense areas where adjacent items are less | 47 // than 2^16 apart, and dense areas where adjacent items are less |
| 47 // than 2^16 apart. | 48 // than 2^16 apart. |
| 48 static void SetUpTestCase() { | 49 static void SetUpTestCase() { |
| 49 // Distribute clusters of prefixes. | 50 // Distribute clusters of prefixes. |
| 50 for (size_t i = 0; i < 250; ++i) { | 51 for (size_t i = 0; i < 250; ++i) { |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 391 // Test writing and reading an empty set. | 392 // Test writing and reading an empty set. |
| 392 { | 393 { |
| 393 std::vector<SBPrefix> prefixes; | 394 std::vector<SBPrefix> prefixes; |
| 394 PrefixSetBuilder builder(prefixes); | 395 PrefixSetBuilder builder(prefixes); |
| 395 ASSERT_TRUE(builder.GetPrefixSetNoHashes()->WriteFile(filename)); | 396 ASSERT_TRUE(builder.GetPrefixSetNoHashes()->WriteFile(filename)); |
| 396 | 397 |
| 397 scoped_ptr<PrefixSet> prefix_set = PrefixSet::LoadFile(filename); | 398 scoped_ptr<PrefixSet> prefix_set = PrefixSet::LoadFile(filename); |
| 398 ASSERT_TRUE(prefix_set.get()); | 399 ASSERT_TRUE(prefix_set.get()); |
| 399 CheckPrefixes(*prefix_set, prefixes); | 400 CheckPrefixes(*prefix_set, prefixes); |
| 400 } | 401 } |
| 402 |
| 403 // Test that full hashes are persisted. |
| 404 { |
| 405 std::vector<SBFullHash> hashes; |
| 406 hashes.push_back(SBFullHashForString("one")); |
| 407 hashes.push_back(SBFullHashForString("two")); |
| 408 hashes.push_back(SBFullHashForString("three")); |
| 409 |
| 410 std::vector<SBPrefix> prefixes(shared_prefixes_); |
| 411 |
| 412 // Remove any collisions from the prefixes. |
| 413 for (size_t i = 0; i < hashes.size(); ++i) { |
| 414 std::vector<SBPrefix>::iterator iter = |
| 415 std::lower_bound(prefixes.begin(), prefixes.end(), hashes[i].prefix); |
| 416 if (iter != prefixes.end() && *iter == hashes[i].prefix) |
| 417 prefixes.erase(iter); |
| 418 } |
| 419 |
| 420 PrefixSetBuilder builder(prefixes); |
| 421 ASSERT_TRUE(builder.GetPrefixSet(hashes)->WriteFile(filename)); |
| 422 |
| 423 scoped_ptr<PrefixSet> prefix_set = PrefixSet::LoadFile(filename); |
| 424 ASSERT_TRUE(prefix_set.get()); |
| 425 CheckPrefixes(*prefix_set, prefixes); |
| 426 |
| 427 EXPECT_TRUE(prefix_set->Exists(hashes[0])); |
| 428 EXPECT_TRUE(prefix_set->Exists(hashes[1])); |
| 429 EXPECT_TRUE(prefix_set->Exists(hashes[2])); |
| 430 EXPECT_FALSE(prefix_set->PrefixExists(hashes[0].prefix)); |
| 431 EXPECT_FALSE(prefix_set->PrefixExists(hashes[1].prefix)); |
| 432 EXPECT_FALSE(prefix_set->PrefixExists(hashes[2].prefix)); |
| 433 } |
| 401 } | 434 } |
| 402 | 435 |
| 403 // Check that |CleanChecksum()| makes an acceptable checksum. | 436 // Check that |CleanChecksum()| makes an acceptable checksum. |
| 404 TEST_F(PrefixSetTest, CorruptionHelpers) { | 437 TEST_F(PrefixSetTest, CorruptionHelpers) { |
| 405 base::FilePath filename; | 438 base::FilePath filename; |
| 406 ASSERT_TRUE(GetPrefixSetFile(&filename)); | 439 ASSERT_TRUE(GetPrefixSetFile(&filename)); |
| 407 | 440 |
| 408 // This will modify data in |index_|, which will fail the digest check. | 441 // This will modify data in |index_|, which will fail the digest check. |
| 409 base::ScopedFILE file(base::OpenFile(filename, "r+b")); | 442 base::ScopedFILE file(base::OpenFile(filename, "r+b")); |
| 410 IncrementIntAt(file.get(), kPayloadOffset, 1); | 443 IncrementIntAt(file.get(), kPayloadOffset, 1); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 458 TEST_F(PrefixSetTest, CorruptionDeltasSize) { | 491 TEST_F(PrefixSetTest, CorruptionDeltasSize) { |
| 459 base::FilePath filename; | 492 base::FilePath filename; |
| 460 ASSERT_TRUE(GetPrefixSetFile(&filename)); | 493 ASSERT_TRUE(GetPrefixSetFile(&filename)); |
| 461 | 494 |
| 462 ASSERT_NO_FATAL_FAILURE( | 495 ASSERT_NO_FATAL_FAILURE( |
| 463 ModifyAndCleanChecksum(filename, kDeltasSizeOffset, 1)); | 496 ModifyAndCleanChecksum(filename, kDeltasSizeOffset, 1)); |
| 464 scoped_ptr<PrefixSet> prefix_set = PrefixSet::LoadFile(filename); | 497 scoped_ptr<PrefixSet> prefix_set = PrefixSet::LoadFile(filename); |
| 465 ASSERT_FALSE(prefix_set.get()); | 498 ASSERT_FALSE(prefix_set.get()); |
| 466 } | 499 } |
| 467 | 500 |
| 501 // Bad |full_hashes_| size is caught by the sanity check. |
| 502 TEST_F(PrefixSetTest, CorruptionFullHashesSize) { |
| 503 base::FilePath filename; |
| 504 ASSERT_TRUE(GetPrefixSetFile(&filename)); |
| 505 |
| 506 ASSERT_NO_FATAL_FAILURE( |
| 507 ModifyAndCleanChecksum(filename, kFullHashesSizeOffset, 1)); |
| 508 scoped_ptr<PrefixSet> prefix_set = PrefixSet::LoadFile(filename); |
| 509 ASSERT_FALSE(prefix_set.get()); |
| 510 } |
| 511 |
| 468 // Test that the digest catches corruption in the middle of the file | 512 // Test that the digest catches corruption in the middle of the file |
| 469 // (in the payload between the header and the digest). | 513 // (in the payload between the header and the digest). |
| 470 TEST_F(PrefixSetTest, CorruptionPayload) { | 514 TEST_F(PrefixSetTest, CorruptionPayload) { |
| 471 base::FilePath filename; | 515 base::FilePath filename; |
| 472 ASSERT_TRUE(GetPrefixSetFile(&filename)); | 516 ASSERT_TRUE(GetPrefixSetFile(&filename)); |
| 473 | 517 |
| 474 base::ScopedFILE file(base::OpenFile(filename, "r+b")); | 518 base::ScopedFILE file(base::OpenFile(filename, "r+b")); |
| 475 ASSERT_NO_FATAL_FAILURE(IncrementIntAt(file.get(), 666, 1)); | 519 ASSERT_NO_FATAL_FAILURE(IncrementIntAt(file.get(), 666, 1)); |
| 476 file.reset(); | 520 file.reset(); |
| 477 scoped_ptr<PrefixSet> prefix_set = PrefixSet::LoadFile(filename); | 521 scoped_ptr<PrefixSet> prefix_set = PrefixSet::LoadFile(filename); |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 660 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &golden_path)); | 704 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &golden_path)); |
| 661 golden_path = golden_path.AppendASCII("SafeBrowsing"); | 705 golden_path = golden_path.AppendASCII("SafeBrowsing"); |
| 662 golden_path = golden_path.AppendASCII(kBasename); | 706 golden_path = golden_path.AppendASCII(kBasename); |
| 663 | 707 |
| 664 scoped_ptr<PrefixSet> prefix_set = PrefixSet::LoadFile(golden_path); | 708 scoped_ptr<PrefixSet> prefix_set = PrefixSet::LoadFile(golden_path); |
| 665 ASSERT_TRUE(prefix_set.get()); | 709 ASSERT_TRUE(prefix_set.get()); |
| 666 CheckPrefixes(*prefix_set, ref_prefixes); | 710 CheckPrefixes(*prefix_set, ref_prefixes); |
| 667 } | 711 } |
| 668 #endif | 712 #endif |
| 669 | 713 |
| 714 // Test that a golden v3 file can be read by the current code. All platforms |
| 715 // generating v3 files are little-endian, so there is no point to testing this |
| 716 // transition if/when a big-endian port is added. |
| 717 #if defined(ARCH_CPU_LITTLE_ENDIAN) |
| 718 TEST_F(PrefixSetTest, Version3) { |
| 719 std::vector<SBPrefix> ref_prefixes; |
| 720 ASSERT_TRUE(ReadReferencePrefixes(&ref_prefixes)); |
| 721 |
| 722 const char kBasename[] = "PrefixSetVersion3"; |
| 723 base::FilePath golden_path; |
| 724 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &golden_path)); |
| 725 golden_path = golden_path.AppendASCII("SafeBrowsing"); |
| 726 golden_path = golden_path.AppendASCII(kBasename); |
| 727 |
| 728 scoped_ptr<PrefixSet> prefix_set = PrefixSet::LoadFile(golden_path); |
| 729 ASSERT_TRUE(prefix_set.get()); |
| 730 CheckPrefixes(*prefix_set, ref_prefixes); |
| 731 |
| 732 const SBFullHash kHash1 = SBFullHashForString("www.evil.com/malware.html"); |
| 733 const SBFullHash kHash2 = SBFullHashForString("www.evil.com/phishing.html"); |
| 734 |
| 735 EXPECT_TRUE(prefix_set->Exists(kHash1)); |
| 736 EXPECT_TRUE(prefix_set->Exists(kHash2)); |
| 737 EXPECT_FALSE(prefix_set->PrefixExists(kHash1.prefix)); |
| 738 EXPECT_FALSE(prefix_set->PrefixExists(kHash2.prefix)); |
| 739 } |
| 740 #endif |
| 741 |
| 670 } // namespace safe_browsing | 742 } // namespace safe_browsing |
| OLD | NEW |