| 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" |
| 11 #include "base/files/scoped_file.h" |
| 11 #include "base/files/scoped_temp_dir.h" | 12 #include "base/files/scoped_temp_dir.h" |
| 12 #include "base/logging.h" | 13 #include "base/logging.h" |
| 13 #include "base/md5.h" | 14 #include "base/md5.h" |
| 14 #include "base/memory/scoped_ptr.h" | 15 #include "base/memory/scoped_ptr.h" |
| 15 #include "base/rand_util.h" | 16 #include "base/rand_util.h" |
| 16 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
| 17 #include "testing/platform_test.h" | 18 #include "testing/platform_test.h" |
| 18 | 19 |
| 19 namespace { | 20 namespace { |
| 20 | 21 |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 147 ASSERT_EQ(file_size, ftell(fp)); | 148 ASSERT_EQ(file_size, ftell(fp)); |
| 148 } | 149 } |
| 149 | 150 |
| 150 // Open |filename| and increment the uint32 at |offset| by |inc|. | 151 // Open |filename| and increment the uint32 at |offset| by |inc|. |
| 151 // Then re-generate the checksum to account for the new contents. | 152 // Then re-generate the checksum to account for the new contents. |
| 152 void ModifyAndCleanChecksum(const base::FilePath& filename, long offset, | 153 void ModifyAndCleanChecksum(const base::FilePath& filename, long offset, |
| 153 int inc) { | 154 int inc) { |
| 154 int64 size_64; | 155 int64 size_64; |
| 155 ASSERT_TRUE(base::GetFileSize(filename, &size_64)); | 156 ASSERT_TRUE(base::GetFileSize(filename, &size_64)); |
| 156 | 157 |
| 157 file_util::ScopedFILE file(base::OpenFile(filename, "r+b")); | 158 base::ScopedFILE file(base::OpenFile(filename, "r+b")); |
| 158 IncrementIntAt(file.get(), offset, inc); | 159 IncrementIntAt(file.get(), offset, inc); |
| 159 CleanChecksum(file.get()); | 160 CleanChecksum(file.get()); |
| 160 file.reset(); | 161 file.reset(); |
| 161 | 162 |
| 162 int64 new_size_64; | 163 int64 new_size_64; |
| 163 ASSERT_TRUE(base::GetFileSize(filename, &new_size_64)); | 164 ASSERT_TRUE(base::GetFileSize(filename, &new_size_64)); |
| 164 ASSERT_EQ(new_size_64, size_64); | 165 ASSERT_EQ(new_size_64, size_64); |
| 165 } | 166 } |
| 166 | 167 |
| 167 // Tests should not modify this shared resource. | 168 // Tests should not modify this shared resource. |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 360 CheckPrefixes(*prefix_set, prefixes); | 361 CheckPrefixes(*prefix_set, prefixes); |
| 361 } | 362 } |
| 362 } | 363 } |
| 363 | 364 |
| 364 // Check that |CleanChecksum()| makes an acceptable checksum. | 365 // Check that |CleanChecksum()| makes an acceptable checksum. |
| 365 TEST_F(PrefixSetTest, CorruptionHelpers) { | 366 TEST_F(PrefixSetTest, CorruptionHelpers) { |
| 366 base::FilePath filename; | 367 base::FilePath filename; |
| 367 ASSERT_TRUE(GetPrefixSetFile(&filename)); | 368 ASSERT_TRUE(GetPrefixSetFile(&filename)); |
| 368 | 369 |
| 369 // This will modify data in |index_|, which will fail the digest check. | 370 // This will modify data in |index_|, which will fail the digest check. |
| 370 file_util::ScopedFILE file(base::OpenFile(filename, "r+b")); | 371 base::ScopedFILE file(base::OpenFile(filename, "r+b")); |
| 371 IncrementIntAt(file.get(), kPayloadOffset, 1); | 372 IncrementIntAt(file.get(), kPayloadOffset, 1); |
| 372 file.reset(); | 373 file.reset(); |
| 373 scoped_ptr<safe_browsing::PrefixSet> | 374 scoped_ptr<safe_browsing::PrefixSet> |
| 374 prefix_set(safe_browsing::PrefixSet::LoadFile(filename)); | 375 prefix_set(safe_browsing::PrefixSet::LoadFile(filename)); |
| 375 ASSERT_FALSE(prefix_set.get()); | 376 ASSERT_FALSE(prefix_set.get()); |
| 376 | 377 |
| 377 // Fix up the checksum and it will read successfully (though the | 378 // Fix up the checksum and it will read successfully (though the |
| 378 // data will be wrong). | 379 // data will be wrong). |
| 379 file.reset(base::OpenFile(filename, "r+b")); | 380 file.reset(base::OpenFile(filename, "r+b")); |
| 380 CleanChecksum(file.get()); | 381 CleanChecksum(file.get()); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 430 prefix_set(safe_browsing::PrefixSet::LoadFile(filename)); | 431 prefix_set(safe_browsing::PrefixSet::LoadFile(filename)); |
| 431 ASSERT_FALSE(prefix_set.get()); | 432 ASSERT_FALSE(prefix_set.get()); |
| 432 } | 433 } |
| 433 | 434 |
| 434 // Test that the digest catches corruption in the middle of the file | 435 // Test that the digest catches corruption in the middle of the file |
| 435 // (in the payload between the header and the digest). | 436 // (in the payload between the header and the digest). |
| 436 TEST_F(PrefixSetTest, CorruptionPayload) { | 437 TEST_F(PrefixSetTest, CorruptionPayload) { |
| 437 base::FilePath filename; | 438 base::FilePath filename; |
| 438 ASSERT_TRUE(GetPrefixSetFile(&filename)); | 439 ASSERT_TRUE(GetPrefixSetFile(&filename)); |
| 439 | 440 |
| 440 file_util::ScopedFILE file(base::OpenFile(filename, "r+b")); | 441 base::ScopedFILE file(base::OpenFile(filename, "r+b")); |
| 441 ASSERT_NO_FATAL_FAILURE(IncrementIntAt(file.get(), 666, 1)); | 442 ASSERT_NO_FATAL_FAILURE(IncrementIntAt(file.get(), 666, 1)); |
| 442 file.reset(); | 443 file.reset(); |
| 443 scoped_ptr<safe_browsing::PrefixSet> | 444 scoped_ptr<safe_browsing::PrefixSet> |
| 444 prefix_set(safe_browsing::PrefixSet::LoadFile(filename)); | 445 prefix_set(safe_browsing::PrefixSet::LoadFile(filename)); |
| 445 ASSERT_FALSE(prefix_set.get()); | 446 ASSERT_FALSE(prefix_set.get()); |
| 446 } | 447 } |
| 447 | 448 |
| 448 // Test corruption in the digest itself. | 449 // Test corruption in the digest itself. |
| 449 TEST_F(PrefixSetTest, CorruptionDigest) { | 450 TEST_F(PrefixSetTest, CorruptionDigest) { |
| 450 base::FilePath filename; | 451 base::FilePath filename; |
| 451 ASSERT_TRUE(GetPrefixSetFile(&filename)); | 452 ASSERT_TRUE(GetPrefixSetFile(&filename)); |
| 452 | 453 |
| 453 int64 size_64; | 454 int64 size_64; |
| 454 ASSERT_TRUE(base::GetFileSize(filename, &size_64)); | 455 ASSERT_TRUE(base::GetFileSize(filename, &size_64)); |
| 455 file_util::ScopedFILE file(base::OpenFile(filename, "r+b")); | 456 base::ScopedFILE file(base::OpenFile(filename, "r+b")); |
| 456 long digest_offset = static_cast<long>(size_64 - sizeof(base::MD5Digest)); | 457 long digest_offset = static_cast<long>(size_64 - sizeof(base::MD5Digest)); |
| 457 ASSERT_NO_FATAL_FAILURE(IncrementIntAt(file.get(), digest_offset, 1)); | 458 ASSERT_NO_FATAL_FAILURE(IncrementIntAt(file.get(), digest_offset, 1)); |
| 458 file.reset(); | 459 file.reset(); |
| 459 scoped_ptr<safe_browsing::PrefixSet> | 460 scoped_ptr<safe_browsing::PrefixSet> |
| 460 prefix_set(safe_browsing::PrefixSet::LoadFile(filename)); | 461 prefix_set(safe_browsing::PrefixSet::LoadFile(filename)); |
| 461 ASSERT_FALSE(prefix_set.get()); | 462 ASSERT_FALSE(prefix_set.get()); |
| 462 } | 463 } |
| 463 | 464 |
| 464 // Test excess data after the digest (fails the size test). | 465 // Test excess data after the digest (fails the size test). |
| 465 TEST_F(PrefixSetTest, CorruptionExcess) { | 466 TEST_F(PrefixSetTest, CorruptionExcess) { |
| 466 base::FilePath filename; | 467 base::FilePath filename; |
| 467 ASSERT_TRUE(GetPrefixSetFile(&filename)); | 468 ASSERT_TRUE(GetPrefixSetFile(&filename)); |
| 468 | 469 |
| 469 // Add some junk to the trunk. | 470 // Add some junk to the trunk. |
| 470 file_util::ScopedFILE file(base::OpenFile(filename, "ab")); | 471 base::ScopedFILE file(base::OpenFile(filename, "ab")); |
| 471 const char buf[] = "im in ur base, killing ur d00dz."; | 472 const char buf[] = "im in ur base, killing ur d00dz."; |
| 472 ASSERT_EQ(strlen(buf), fwrite(buf, 1, strlen(buf), file.get())); | 473 ASSERT_EQ(strlen(buf), fwrite(buf, 1, strlen(buf), file.get())); |
| 473 file.reset(); | 474 file.reset(); |
| 474 scoped_ptr<safe_browsing::PrefixSet> | 475 scoped_ptr<safe_browsing::PrefixSet> |
| 475 prefix_set(safe_browsing::PrefixSet::LoadFile(filename)); | 476 prefix_set(safe_browsing::PrefixSet::LoadFile(filename)); |
| 476 ASSERT_FALSE(prefix_set.get()); | 477 ASSERT_FALSE(prefix_set.get()); |
| 477 } | 478 } |
| 478 | 479 |
| 479 // Test that files which had 64-bit size_t are discarded. | 480 // Test that files which had 64-bit size_t are discarded. |
| 480 TEST_F(PrefixSetTest, SizeTRecovery) { | 481 TEST_F(PrefixSetTest, SizeTRecovery) { |
| 481 base::FilePath filename; | 482 base::FilePath filename; |
| 482 ASSERT_TRUE(GetPrefixSetFile(&filename)); | 483 ASSERT_TRUE(GetPrefixSetFile(&filename)); |
| 483 | 484 |
| 484 // Open the file for rewrite. | 485 // Open the file for rewrite. |
| 485 file_util::ScopedFILE file(base::OpenFile(filename, "r+b")); | 486 base::ScopedFILE file(base::OpenFile(filename, "r+b")); |
| 486 | 487 |
| 487 // Leave existing magic and version. | 488 // Leave existing magic and version. |
| 488 ASSERT_NE(-1, fseek(file.get(), sizeof(uint32) * 2, SEEK_SET)); | 489 ASSERT_NE(-1, fseek(file.get(), sizeof(uint32) * 2, SEEK_SET)); |
| 489 | 490 |
| 490 // Indicate two index values and two deltas. | 491 // Indicate two index values and two deltas. |
| 491 uint32 val = 2; | 492 uint32 val = 2; |
| 492 ASSERT_EQ(sizeof(val), fwrite(&val, 1, sizeof(val), file.get())); | 493 ASSERT_EQ(sizeof(val), fwrite(&val, 1, sizeof(val), file.get())); |
| 493 ASSERT_EQ(sizeof(val), fwrite(&val, 1, sizeof(val), file.get())); | 494 ASSERT_EQ(sizeof(val), fwrite(&val, 1, sizeof(val), file.get())); |
| 494 | 495 |
| 495 // Write two index values with 64-bit "size_t". | 496 // Write two index values with 64-bit "size_t". |
| (...skipping 22 matching lines...) Expand all Loading... |
| 518 prefix_set(safe_browsing::PrefixSet::LoadFile(filename)); | 519 prefix_set(safe_browsing::PrefixSet::LoadFile(filename)); |
| 519 ASSERT_FALSE(prefix_set.get()); | 520 ASSERT_FALSE(prefix_set.get()); |
| 520 } | 521 } |
| 521 | 522 |
| 522 // Test that a version 1 file is re-ordered correctly on read. | 523 // Test that a version 1 file is re-ordered correctly on read. |
| 523 TEST_F(PrefixSetTest, ReadWriteSigned) { | 524 TEST_F(PrefixSetTest, ReadWriteSigned) { |
| 524 base::FilePath filename; | 525 base::FilePath filename; |
| 525 ASSERT_TRUE(GetPrefixSetFile(&filename)); | 526 ASSERT_TRUE(GetPrefixSetFile(&filename)); |
| 526 | 527 |
| 527 // Open the file for rewrite. | 528 // Open the file for rewrite. |
| 528 file_util::ScopedFILE file(base::OpenFile(filename, "r+b")); | 529 base::ScopedFILE file(base::OpenFile(filename, "r+b")); |
| 529 | 530 |
| 530 // Leave existing magic. | 531 // Leave existing magic. |
| 531 ASSERT_NE(-1, fseek(file.get(), sizeof(uint32), SEEK_SET)); | 532 ASSERT_NE(-1, fseek(file.get(), sizeof(uint32), SEEK_SET)); |
| 532 | 533 |
| 533 // Version 1. | 534 // Version 1. |
| 534 uint32 version = 1; | 535 uint32 version = 1; |
| 535 ASSERT_EQ(sizeof(version), fwrite(&version, 1, sizeof(version), file.get())); | 536 ASSERT_EQ(sizeof(version), fwrite(&version, 1, sizeof(version), file.get())); |
| 536 | 537 |
| 537 // Indicate two index values and two deltas. | 538 // Indicate two index values and two deltas. |
| 538 uint32 val = 2; | 539 uint32 val = 2; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 576 std::vector<SBPrefix> prefixes_copy; | 577 std::vector<SBPrefix> prefixes_copy; |
| 577 prefix_set->GetPrefixes(&prefixes_copy); | 578 prefix_set->GetPrefixes(&prefixes_copy); |
| 578 EXPECT_EQ(prefixes_copy.size(), 4u); | 579 EXPECT_EQ(prefixes_copy.size(), 4u); |
| 579 EXPECT_EQ(prefixes_copy[0], 1000u); | 580 EXPECT_EQ(prefixes_copy[0], 1000u); |
| 580 EXPECT_EQ(prefixes_copy[1], 1023u); | 581 EXPECT_EQ(prefixes_copy[1], 1023u); |
| 581 EXPECT_EQ(prefixes_copy[2], static_cast<uint32>(-1000)); | 582 EXPECT_EQ(prefixes_copy[2], static_cast<uint32>(-1000)); |
| 582 EXPECT_EQ(prefixes_copy[3], static_cast<uint32>(-1000 + 23)); | 583 EXPECT_EQ(prefixes_copy[3], static_cast<uint32>(-1000 + 23)); |
| 583 } | 584 } |
| 584 | 585 |
| 585 } // namespace | 586 } // namespace |
| OLD | NEW |