| 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 #include <set> | 9 #include <set> |
| 10 #include <string> | 10 #include <string> |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 214 // Test that a small sparse random input works. | 214 // Test that a small sparse random input works. |
| 215 TEST_F(PrefixSetTest, Baseline) { | 215 TEST_F(PrefixSetTest, Baseline) { |
| 216 PrefixSetBuilder builder(shared_prefixes_); | 216 PrefixSetBuilder builder(shared_prefixes_); |
| 217 CheckPrefixes(*builder.GetPrefixSetNoHashes(), shared_prefixes_); | 217 CheckPrefixes(*builder.GetPrefixSetNoHashes(), shared_prefixes_); |
| 218 } | 218 } |
| 219 | 219 |
| 220 // Test that the empty set doesn't appear to have anything in it. | 220 // Test that the empty set doesn't appear to have anything in it. |
| 221 TEST_F(PrefixSetTest, Empty) { | 221 TEST_F(PrefixSetTest, Empty) { |
| 222 const std::vector<SBPrefix> empty; | 222 const std::vector<SBPrefix> empty; |
| 223 PrefixSetBuilder builder(empty); | 223 PrefixSetBuilder builder(empty); |
| 224 scoped_ptr<PrefixSet> prefix_set = builder.GetPrefixSetNoHashes(); | 224 scoped_ptr<const PrefixSet> prefix_set = builder.GetPrefixSetNoHashes(); |
| 225 for (size_t i = 0; i < shared_prefixes_.size(); ++i) { | 225 for (size_t i = 0; i < shared_prefixes_.size(); ++i) { |
| 226 EXPECT_FALSE(prefix_set->PrefixExists(shared_prefixes_[i])); | 226 EXPECT_FALSE(prefix_set->PrefixExists(shared_prefixes_[i])); |
| 227 } | 227 } |
| 228 } | 228 } |
| 229 | 229 |
| 230 // Single-element set should work fine. | 230 // Single-element set should work fine. |
| 231 TEST_F(PrefixSetTest, OneElement) { | 231 TEST_F(PrefixSetTest, OneElement) { |
| 232 const std::vector<SBPrefix> prefixes(100, 0u); | 232 const std::vector<SBPrefix> prefixes(100, 0u); |
| 233 PrefixSetBuilder builder(prefixes); | 233 PrefixSetBuilder builder(prefixes); |
| 234 scoped_ptr<PrefixSet> prefix_set = builder.GetPrefixSetNoHashes(); | 234 scoped_ptr<const PrefixSet> prefix_set = builder.GetPrefixSetNoHashes(); |
| 235 EXPECT_FALSE(prefix_set->PrefixExists(static_cast<SBPrefix>(-1))); | 235 EXPECT_FALSE(prefix_set->PrefixExists(static_cast<SBPrefix>(-1))); |
| 236 EXPECT_TRUE(prefix_set->PrefixExists(prefixes[0])); | 236 EXPECT_TRUE(prefix_set->PrefixExists(prefixes[0])); |
| 237 EXPECT_FALSE(prefix_set->PrefixExists(1u)); | 237 EXPECT_FALSE(prefix_set->PrefixExists(1u)); |
| 238 | 238 |
| 239 // Check that |GetPrefixes()| returns the same set of prefixes as | 239 // Check that |GetPrefixes()| returns the same set of prefixes as |
| 240 // was passed in. | 240 // was passed in. |
| 241 std::vector<SBPrefix> prefixes_copy; | 241 std::vector<SBPrefix> prefixes_copy; |
| 242 prefix_set->GetPrefixes(&prefixes_copy); | 242 prefix_set->GetPrefixes(&prefixes_copy); |
| 243 EXPECT_EQ(1U, prefixes_copy.size()); | 243 EXPECT_EQ(1U, prefixes_copy.size()); |
| 244 EXPECT_EQ(prefixes[0], prefixes_copy[0]); | 244 EXPECT_EQ(prefixes[0], prefixes_copy[0]); |
| 245 } | 245 } |
| 246 | 246 |
| 247 // Edges of the 32-bit integer range. | 247 // Edges of the 32-bit integer range. |
| 248 TEST_F(PrefixSetTest, IntMinMax) { | 248 TEST_F(PrefixSetTest, IntMinMax) { |
| 249 std::vector<SBPrefix> prefixes; | 249 std::vector<SBPrefix> prefixes; |
| 250 | 250 |
| 251 // Using bit patterns rather than portable constants because this | 251 // Using bit patterns rather than portable constants because this |
| 252 // really is testing how the entire 32-bit integer range is handled. | 252 // really is testing how the entire 32-bit integer range is handled. |
| 253 prefixes.push_back(0x00000000); | 253 prefixes.push_back(0x00000000); |
| 254 prefixes.push_back(0x0000FFFF); | 254 prefixes.push_back(0x0000FFFF); |
| 255 prefixes.push_back(0x7FFF0000); | 255 prefixes.push_back(0x7FFF0000); |
| 256 prefixes.push_back(0x7FFFFFFF); | 256 prefixes.push_back(0x7FFFFFFF); |
| 257 prefixes.push_back(0x80000000); | 257 prefixes.push_back(0x80000000); |
| 258 prefixes.push_back(0x8000FFFF); | 258 prefixes.push_back(0x8000FFFF); |
| 259 prefixes.push_back(0xFFFF0000); | 259 prefixes.push_back(0xFFFF0000); |
| 260 prefixes.push_back(0xFFFFFFFF); | 260 prefixes.push_back(0xFFFFFFFF); |
| 261 | 261 |
| 262 std::sort(prefixes.begin(), prefixes.end()); | 262 std::sort(prefixes.begin(), prefixes.end()); |
| 263 PrefixSetBuilder builder(prefixes); | 263 PrefixSetBuilder builder(prefixes); |
| 264 scoped_ptr<PrefixSet> prefix_set = builder.GetPrefixSetNoHashes(); | 264 scoped_ptr<const PrefixSet> prefix_set = builder.GetPrefixSetNoHashes(); |
| 265 | 265 |
| 266 // Check that |GetPrefixes()| returns the same set of prefixes as | 266 // Check that |GetPrefixes()| returns the same set of prefixes as |
| 267 // was passed in. | 267 // was passed in. |
| 268 std::vector<SBPrefix> prefixes_copy; | 268 std::vector<SBPrefix> prefixes_copy; |
| 269 prefix_set->GetPrefixes(&prefixes_copy); | 269 prefix_set->GetPrefixes(&prefixes_copy); |
| 270 ASSERT_EQ(prefixes_copy.size(), prefixes.size()); | 270 ASSERT_EQ(prefixes_copy.size(), prefixes.size()); |
| 271 EXPECT_TRUE(std::equal(prefixes.begin(), prefixes.end(), | 271 EXPECT_TRUE(std::equal(prefixes.begin(), prefixes.end(), |
| 272 prefixes_copy.begin())); | 272 prefixes_copy.begin())); |
| 273 } | 273 } |
| 274 | 274 |
| 275 // A range with only large deltas. | 275 // A range with only large deltas. |
| 276 TEST_F(PrefixSetTest, AllBig) { | 276 TEST_F(PrefixSetTest, AllBig) { |
| 277 std::vector<SBPrefix> prefixes; | 277 std::vector<SBPrefix> prefixes; |
| 278 | 278 |
| 279 const unsigned kDelta = 10 * 1000 * 1000; | 279 const unsigned kDelta = 10 * 1000 * 1000; |
| 280 for (SBPrefix prefix = kHighBitSet; | 280 for (SBPrefix prefix = kHighBitSet; |
| 281 prefix < kHighBitClear; prefix += kDelta) { | 281 prefix < kHighBitClear; prefix += kDelta) { |
| 282 prefixes.push_back(prefix); | 282 prefixes.push_back(prefix); |
| 283 } | 283 } |
| 284 | 284 |
| 285 std::sort(prefixes.begin(), prefixes.end()); | 285 std::sort(prefixes.begin(), prefixes.end()); |
| 286 PrefixSetBuilder builder(prefixes); | 286 PrefixSetBuilder builder(prefixes); |
| 287 scoped_ptr<PrefixSet> prefix_set = builder.GetPrefixSetNoHashes(); | 287 scoped_ptr<const PrefixSet> prefix_set = builder.GetPrefixSetNoHashes(); |
| 288 | 288 |
| 289 // Check that |GetPrefixes()| returns the same set of prefixes as | 289 // Check that |GetPrefixes()| returns the same set of prefixes as |
| 290 // was passed in. | 290 // was passed in. |
| 291 std::vector<SBPrefix> prefixes_copy; | 291 std::vector<SBPrefix> prefixes_copy; |
| 292 prefix_set->GetPrefixes(&prefixes_copy); | 292 prefix_set->GetPrefixes(&prefixes_copy); |
| 293 prefixes.erase(std::unique(prefixes.begin(), prefixes.end()), prefixes.end()); | 293 prefixes.erase(std::unique(prefixes.begin(), prefixes.end()), prefixes.end()); |
| 294 EXPECT_EQ(prefixes_copy.size(), prefixes.size()); | 294 EXPECT_EQ(prefixes_copy.size(), prefixes.size()); |
| 295 EXPECT_TRUE(std::equal(prefixes.begin(), prefixes.end(), | 295 EXPECT_TRUE(std::equal(prefixes.begin(), prefixes.end(), |
| 296 prefixes_copy.begin())); | 296 prefixes_copy.begin())); |
| 297 } | 297 } |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 331 prefix = kHighBitClear - delta * 1000; | 331 prefix = kHighBitClear - delta * 1000; |
| 332 prefixes.push_back(prefix); | 332 prefixes.push_back(prefix); |
| 333 for (int i = 0; i < 1000; ++i) { | 333 for (int i = 0; i < 1000; ++i) { |
| 334 prefix += delta; | 334 prefix += delta; |
| 335 prefixes.push_back(prefix); | 335 prefixes.push_back(prefix); |
| 336 delta--; | 336 delta--; |
| 337 } | 337 } |
| 338 | 338 |
| 339 std::sort(prefixes.begin(), prefixes.end()); | 339 std::sort(prefixes.begin(), prefixes.end()); |
| 340 PrefixSetBuilder builder(prefixes); | 340 PrefixSetBuilder builder(prefixes); |
| 341 scoped_ptr<PrefixSet> prefix_set = builder.GetPrefixSetNoHashes(); | 341 scoped_ptr<const PrefixSet> prefix_set = builder.GetPrefixSetNoHashes(); |
| 342 | 342 |
| 343 // Check that |GetPrefixes()| returns the same set of prefixes as | 343 // Check that |GetPrefixes()| returns the same set of prefixes as |
| 344 // was passed in. | 344 // was passed in. |
| 345 std::vector<SBPrefix> prefixes_copy; | 345 std::vector<SBPrefix> prefixes_copy; |
| 346 prefix_set->GetPrefixes(&prefixes_copy); | 346 prefix_set->GetPrefixes(&prefixes_copy); |
| 347 prefixes.erase(std::unique(prefixes.begin(), prefixes.end()), prefixes.end()); | 347 prefixes.erase(std::unique(prefixes.begin(), prefixes.end()), prefixes.end()); |
| 348 EXPECT_EQ(prefixes_copy.size(), prefixes.size()); | 348 EXPECT_EQ(prefixes_copy.size(), prefixes.size()); |
| 349 EXPECT_TRUE(std::equal(prefixes.begin(), prefixes.end(), | 349 EXPECT_TRUE(std::equal(prefixes.begin(), prefixes.end(), |
| 350 prefixes_copy.begin())); | 350 prefixes_copy.begin())); |
| 351 | 351 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 365 } | 365 } |
| 366 | 366 |
| 367 // Test writing a prefix set to disk and reading it back in. | 367 // Test writing a prefix set to disk and reading it back in. |
| 368 TEST_F(PrefixSetTest, ReadWrite) { | 368 TEST_F(PrefixSetTest, ReadWrite) { |
| 369 base::FilePath filename; | 369 base::FilePath filename; |
| 370 | 370 |
| 371 // Write the sample prefix set out, read it back in, and check all | 371 // Write the sample prefix set out, read it back in, and check all |
| 372 // the prefixes. Leaves the path in |filename|. | 372 // the prefixes. Leaves the path in |filename|. |
| 373 { | 373 { |
| 374 ASSERT_TRUE(GetPrefixSetFile(&filename)); | 374 ASSERT_TRUE(GetPrefixSetFile(&filename)); |
| 375 scoped_ptr<PrefixSet> prefix_set = PrefixSet::LoadFile(filename); | 375 scoped_ptr<const PrefixSet> prefix_set = PrefixSet::LoadFile(filename); |
| 376 ASSERT_TRUE(prefix_set.get()); | 376 ASSERT_TRUE(prefix_set.get()); |
| 377 CheckPrefixes(*prefix_set, shared_prefixes_); | 377 CheckPrefixes(*prefix_set, shared_prefixes_); |
| 378 } | 378 } |
| 379 | 379 |
| 380 // Test writing and reading a very sparse set containing no deltas. | 380 // Test writing and reading a very sparse set containing no deltas. |
| 381 { | 381 { |
| 382 std::vector<SBPrefix> prefixes; | 382 std::vector<SBPrefix> prefixes; |
| 383 prefixes.push_back(kHighBitClear); | 383 prefixes.push_back(kHighBitClear); |
| 384 prefixes.push_back(kHighBitSet); | 384 prefixes.push_back(kHighBitSet); |
| 385 | 385 |
| 386 PrefixSetBuilder builder(prefixes); | 386 PrefixSetBuilder builder(prefixes); |
| 387 ASSERT_TRUE(builder.GetPrefixSetNoHashes()->WriteFile(filename)); | 387 ASSERT_TRUE(builder.GetPrefixSetNoHashes()->WriteFile(filename)); |
| 388 | 388 |
| 389 scoped_ptr<PrefixSet> prefix_set = PrefixSet::LoadFile(filename); | 389 scoped_ptr<const PrefixSet> prefix_set = PrefixSet::LoadFile(filename); |
| 390 ASSERT_TRUE(prefix_set.get()); | 390 ASSERT_TRUE(prefix_set.get()); |
| 391 CheckPrefixes(*prefix_set, prefixes); | 391 CheckPrefixes(*prefix_set, prefixes); |
| 392 } | 392 } |
| 393 | 393 |
| 394 // Test writing and reading an empty set. | 394 // Test writing and reading an empty set. |
| 395 { | 395 { |
| 396 std::vector<SBPrefix> prefixes; | 396 std::vector<SBPrefix> prefixes; |
| 397 PrefixSetBuilder builder(prefixes); | 397 PrefixSetBuilder builder(prefixes); |
| 398 ASSERT_TRUE(builder.GetPrefixSetNoHashes()->WriteFile(filename)); | 398 ASSERT_TRUE(builder.GetPrefixSetNoHashes()->WriteFile(filename)); |
| 399 | 399 |
| 400 scoped_ptr<PrefixSet> prefix_set = PrefixSet::LoadFile(filename); | 400 scoped_ptr<const PrefixSet> prefix_set = PrefixSet::LoadFile(filename); |
| 401 ASSERT_TRUE(prefix_set.get()); | 401 ASSERT_TRUE(prefix_set.get()); |
| 402 CheckPrefixes(*prefix_set, prefixes); | 402 CheckPrefixes(*prefix_set, prefixes); |
| 403 } | 403 } |
| 404 | 404 |
| 405 // Test that full hashes are persisted. | 405 // Test that full hashes are persisted. |
| 406 { | 406 { |
| 407 std::vector<SBFullHash> hashes; | 407 std::vector<SBFullHash> hashes; |
| 408 hashes.push_back(SBFullHashForString("one")); | 408 hashes.push_back(SBFullHashForString("one")); |
| 409 hashes.push_back(SBFullHashForString("two")); | 409 hashes.push_back(SBFullHashForString("two")); |
| 410 hashes.push_back(SBFullHashForString("three")); | 410 hashes.push_back(SBFullHashForString("three")); |
| 411 | 411 |
| 412 std::vector<SBPrefix> prefixes(shared_prefixes_); | 412 std::vector<SBPrefix> prefixes(shared_prefixes_); |
| 413 | 413 |
| 414 // Remove any collisions from the prefixes. | 414 // Remove any collisions from the prefixes. |
| 415 for (size_t i = 0; i < hashes.size(); ++i) { | 415 for (size_t i = 0; i < hashes.size(); ++i) { |
| 416 std::vector<SBPrefix>::iterator iter = | 416 std::vector<SBPrefix>::iterator iter = |
| 417 std::lower_bound(prefixes.begin(), prefixes.end(), hashes[i].prefix); | 417 std::lower_bound(prefixes.begin(), prefixes.end(), hashes[i].prefix); |
| 418 if (iter != prefixes.end() && *iter == hashes[i].prefix) | 418 if (iter != prefixes.end() && *iter == hashes[i].prefix) |
| 419 prefixes.erase(iter); | 419 prefixes.erase(iter); |
| 420 } | 420 } |
| 421 | 421 |
| 422 PrefixSetBuilder builder(prefixes); | 422 PrefixSetBuilder builder(prefixes); |
| 423 ASSERT_TRUE(builder.GetPrefixSet(hashes)->WriteFile(filename)); | 423 ASSERT_TRUE(builder.GetPrefixSet(hashes)->WriteFile(filename)); |
| 424 | 424 |
| 425 scoped_ptr<PrefixSet> prefix_set = PrefixSet::LoadFile(filename); | 425 scoped_ptr<const PrefixSet> prefix_set = PrefixSet::LoadFile(filename); |
| 426 ASSERT_TRUE(prefix_set.get()); | 426 ASSERT_TRUE(prefix_set.get()); |
| 427 CheckPrefixes(*prefix_set, prefixes); | 427 CheckPrefixes(*prefix_set, prefixes); |
| 428 | 428 |
| 429 EXPECT_TRUE(prefix_set->Exists(hashes[0])); | 429 EXPECT_TRUE(prefix_set->Exists(hashes[0])); |
| 430 EXPECT_TRUE(prefix_set->Exists(hashes[1])); | 430 EXPECT_TRUE(prefix_set->Exists(hashes[1])); |
| 431 EXPECT_TRUE(prefix_set->Exists(hashes[2])); | 431 EXPECT_TRUE(prefix_set->Exists(hashes[2])); |
| 432 EXPECT_FALSE(prefix_set->PrefixExists(hashes[0].prefix)); | 432 EXPECT_FALSE(prefix_set->PrefixExists(hashes[0].prefix)); |
| 433 EXPECT_FALSE(prefix_set->PrefixExists(hashes[1].prefix)); | 433 EXPECT_FALSE(prefix_set->PrefixExists(hashes[1].prefix)); |
| 434 EXPECT_FALSE(prefix_set->PrefixExists(hashes[2].prefix)); | 434 EXPECT_FALSE(prefix_set->PrefixExists(hashes[2].prefix)); |
| 435 } | 435 } |
| 436 } | 436 } |
| 437 | 437 |
| 438 // Check that |CleanChecksum()| makes an acceptable checksum. | 438 // Check that |CleanChecksum()| makes an acceptable checksum. |
| 439 TEST_F(PrefixSetTest, CorruptionHelpers) { | 439 TEST_F(PrefixSetTest, CorruptionHelpers) { |
| 440 base::FilePath filename; | 440 base::FilePath filename; |
| 441 ASSERT_TRUE(GetPrefixSetFile(&filename)); | 441 ASSERT_TRUE(GetPrefixSetFile(&filename)); |
| 442 | 442 |
| 443 // This will modify data in |index_|, which will fail the digest check. | 443 // This will modify data in |index_|, which will fail the digest check. |
| 444 base::ScopedFILE file(base::OpenFile(filename, "r+b")); | 444 base::ScopedFILE file(base::OpenFile(filename, "r+b")); |
| 445 IncrementIntAt(file.get(), kPayloadOffset, 1); | 445 IncrementIntAt(file.get(), kPayloadOffset, 1); |
| 446 file.reset(); | 446 file.reset(); |
| 447 scoped_ptr<PrefixSet> prefix_set = PrefixSet::LoadFile(filename); | 447 scoped_ptr<const PrefixSet> prefix_set = PrefixSet::LoadFile(filename); |
| 448 ASSERT_FALSE(prefix_set.get()); | 448 ASSERT_FALSE(prefix_set.get()); |
| 449 | 449 |
| 450 // Fix up the checksum and it will read successfully (though the | 450 // Fix up the checksum and it will read successfully (though the |
| 451 // data will be wrong). | 451 // data will be wrong). |
| 452 file.reset(base::OpenFile(filename, "r+b")); | 452 file.reset(base::OpenFile(filename, "r+b")); |
| 453 CleanChecksum(file.get()); | 453 CleanChecksum(file.get()); |
| 454 file.reset(); | 454 file.reset(); |
| 455 prefix_set = PrefixSet::LoadFile(filename); | 455 prefix_set = PrefixSet::LoadFile(filename); |
| 456 ASSERT_TRUE(prefix_set.get()); | 456 ASSERT_TRUE(prefix_set.get()); |
| 457 } | 457 } |
| 458 | 458 |
| 459 // Bad magic is caught by the sanity check. | 459 // Bad magic is caught by the sanity check. |
| 460 TEST_F(PrefixSetTest, CorruptionMagic) { | 460 TEST_F(PrefixSetTest, CorruptionMagic) { |
| 461 base::FilePath filename; | 461 base::FilePath filename; |
| 462 ASSERT_TRUE(GetPrefixSetFile(&filename)); | 462 ASSERT_TRUE(GetPrefixSetFile(&filename)); |
| 463 | 463 |
| 464 ASSERT_NO_FATAL_FAILURE( | 464 ASSERT_NO_FATAL_FAILURE( |
| 465 ModifyAndCleanChecksum(filename, kMagicOffset, 1)); | 465 ModifyAndCleanChecksum(filename, kMagicOffset, 1)); |
| 466 scoped_ptr<PrefixSet> prefix_set = PrefixSet::LoadFile(filename); | 466 scoped_ptr<const PrefixSet> prefix_set = PrefixSet::LoadFile(filename); |
| 467 ASSERT_FALSE(prefix_set.get()); | 467 ASSERT_FALSE(prefix_set.get()); |
| 468 } | 468 } |
| 469 | 469 |
| 470 // Bad version is caught by the sanity check. | 470 // Bad version is caught by the sanity check. |
| 471 TEST_F(PrefixSetTest, CorruptionVersion) { | 471 TEST_F(PrefixSetTest, CorruptionVersion) { |
| 472 base::FilePath filename; | 472 base::FilePath filename; |
| 473 ASSERT_TRUE(GetPrefixSetFile(&filename)); | 473 ASSERT_TRUE(GetPrefixSetFile(&filename)); |
| 474 | 474 |
| 475 ASSERT_NO_FATAL_FAILURE( | 475 ASSERT_NO_FATAL_FAILURE( |
| 476 ModifyAndCleanChecksum(filename, kVersionOffset, 10)); | 476 ModifyAndCleanChecksum(filename, kVersionOffset, 10)); |
| 477 scoped_ptr<PrefixSet> prefix_set = PrefixSet::LoadFile(filename); | 477 scoped_ptr<const PrefixSet> prefix_set = PrefixSet::LoadFile(filename); |
| 478 ASSERT_FALSE(prefix_set.get()); | 478 ASSERT_FALSE(prefix_set.get()); |
| 479 } | 479 } |
| 480 | 480 |
| 481 // Bad |index_| size is caught by the sanity check. | 481 // Bad |index_| size is caught by the sanity check. |
| 482 TEST_F(PrefixSetTest, CorruptionIndexSize) { | 482 TEST_F(PrefixSetTest, CorruptionIndexSize) { |
| 483 base::FilePath filename; | 483 base::FilePath filename; |
| 484 ASSERT_TRUE(GetPrefixSetFile(&filename)); | 484 ASSERT_TRUE(GetPrefixSetFile(&filename)); |
| 485 | 485 |
| 486 ASSERT_NO_FATAL_FAILURE( | 486 ASSERT_NO_FATAL_FAILURE( |
| 487 ModifyAndCleanChecksum(filename, kIndexSizeOffset, 1)); | 487 ModifyAndCleanChecksum(filename, kIndexSizeOffset, 1)); |
| 488 scoped_ptr<PrefixSet> prefix_set = PrefixSet::LoadFile(filename); | 488 scoped_ptr<const PrefixSet> prefix_set = PrefixSet::LoadFile(filename); |
| 489 ASSERT_FALSE(prefix_set.get()); | 489 ASSERT_FALSE(prefix_set.get()); |
| 490 } | 490 } |
| 491 | 491 |
| 492 // Bad |deltas_| size is caught by the sanity check. | 492 // Bad |deltas_| size is caught by the sanity check. |
| 493 TEST_F(PrefixSetTest, CorruptionDeltasSize) { | 493 TEST_F(PrefixSetTest, CorruptionDeltasSize) { |
| 494 base::FilePath filename; | 494 base::FilePath filename; |
| 495 ASSERT_TRUE(GetPrefixSetFile(&filename)); | 495 ASSERT_TRUE(GetPrefixSetFile(&filename)); |
| 496 | 496 |
| 497 ASSERT_NO_FATAL_FAILURE( | 497 ASSERT_NO_FATAL_FAILURE( |
| 498 ModifyAndCleanChecksum(filename, kDeltasSizeOffset, 1)); | 498 ModifyAndCleanChecksum(filename, kDeltasSizeOffset, 1)); |
| 499 scoped_ptr<PrefixSet> prefix_set = PrefixSet::LoadFile(filename); | 499 scoped_ptr<const PrefixSet> prefix_set = PrefixSet::LoadFile(filename); |
| 500 ASSERT_FALSE(prefix_set.get()); | 500 ASSERT_FALSE(prefix_set.get()); |
| 501 } | 501 } |
| 502 | 502 |
| 503 // Bad |full_hashes_| size is caught by the sanity check. | 503 // Bad |full_hashes_| size is caught by the sanity check. |
| 504 TEST_F(PrefixSetTest, CorruptionFullHashesSize) { | 504 TEST_F(PrefixSetTest, CorruptionFullHashesSize) { |
| 505 base::FilePath filename; | 505 base::FilePath filename; |
| 506 ASSERT_TRUE(GetPrefixSetFile(&filename)); | 506 ASSERT_TRUE(GetPrefixSetFile(&filename)); |
| 507 | 507 |
| 508 ASSERT_NO_FATAL_FAILURE( | 508 ASSERT_NO_FATAL_FAILURE( |
| 509 ModifyAndCleanChecksum(filename, kFullHashesSizeOffset, 1)); | 509 ModifyAndCleanChecksum(filename, kFullHashesSizeOffset, 1)); |
| 510 scoped_ptr<PrefixSet> prefix_set = PrefixSet::LoadFile(filename); | 510 scoped_ptr<const PrefixSet> prefix_set = PrefixSet::LoadFile(filename); |
| 511 ASSERT_FALSE(prefix_set.get()); | 511 ASSERT_FALSE(prefix_set.get()); |
| 512 } | 512 } |
| 513 | 513 |
| 514 // Test that the digest catches corruption in the middle of the file | 514 // Test that the digest catches corruption in the middle of the file |
| 515 // (in the payload between the header and the digest). | 515 // (in the payload between the header and the digest). |
| 516 TEST_F(PrefixSetTest, CorruptionPayload) { | 516 TEST_F(PrefixSetTest, CorruptionPayload) { |
| 517 base::FilePath filename; | 517 base::FilePath filename; |
| 518 ASSERT_TRUE(GetPrefixSetFile(&filename)); | 518 ASSERT_TRUE(GetPrefixSetFile(&filename)); |
| 519 | 519 |
| 520 base::ScopedFILE file(base::OpenFile(filename, "r+b")); | 520 base::ScopedFILE file(base::OpenFile(filename, "r+b")); |
| 521 ASSERT_NO_FATAL_FAILURE(IncrementIntAt(file.get(), 666, 1)); | 521 ASSERT_NO_FATAL_FAILURE(IncrementIntAt(file.get(), 666, 1)); |
| 522 file.reset(); | 522 file.reset(); |
| 523 scoped_ptr<PrefixSet> prefix_set = PrefixSet::LoadFile(filename); | 523 scoped_ptr<const PrefixSet> prefix_set = PrefixSet::LoadFile(filename); |
| 524 ASSERT_FALSE(prefix_set.get()); | 524 ASSERT_FALSE(prefix_set.get()); |
| 525 } | 525 } |
| 526 | 526 |
| 527 // Test corruption in the digest itself. | 527 // Test corruption in the digest itself. |
| 528 TEST_F(PrefixSetTest, CorruptionDigest) { | 528 TEST_F(PrefixSetTest, CorruptionDigest) { |
| 529 base::FilePath filename; | 529 base::FilePath filename; |
| 530 ASSERT_TRUE(GetPrefixSetFile(&filename)); | 530 ASSERT_TRUE(GetPrefixSetFile(&filename)); |
| 531 | 531 |
| 532 int64 size_64; | 532 int64 size_64; |
| 533 ASSERT_TRUE(base::GetFileSize(filename, &size_64)); | 533 ASSERT_TRUE(base::GetFileSize(filename, &size_64)); |
| 534 base::ScopedFILE file(base::OpenFile(filename, "r+b")); | 534 base::ScopedFILE file(base::OpenFile(filename, "r+b")); |
| 535 long digest_offset = static_cast<long>(size_64 - sizeof(base::MD5Digest)); | 535 long digest_offset = static_cast<long>(size_64 - sizeof(base::MD5Digest)); |
| 536 ASSERT_NO_FATAL_FAILURE(IncrementIntAt(file.get(), digest_offset, 1)); | 536 ASSERT_NO_FATAL_FAILURE(IncrementIntAt(file.get(), digest_offset, 1)); |
| 537 file.reset(); | 537 file.reset(); |
| 538 scoped_ptr<PrefixSet> prefix_set = PrefixSet::LoadFile(filename); | 538 scoped_ptr<const PrefixSet> prefix_set = PrefixSet::LoadFile(filename); |
| 539 ASSERT_FALSE(prefix_set.get()); | 539 ASSERT_FALSE(prefix_set.get()); |
| 540 } | 540 } |
| 541 | 541 |
| 542 // Test excess data after the digest (fails the size test). | 542 // Test excess data after the digest (fails the size test). |
| 543 TEST_F(PrefixSetTest, CorruptionExcess) { | 543 TEST_F(PrefixSetTest, CorruptionExcess) { |
| 544 base::FilePath filename; | 544 base::FilePath filename; |
| 545 ASSERT_TRUE(GetPrefixSetFile(&filename)); | 545 ASSERT_TRUE(GetPrefixSetFile(&filename)); |
| 546 | 546 |
| 547 // Add some junk to the trunk. | 547 // Add some junk to the trunk. |
| 548 base::ScopedFILE file(base::OpenFile(filename, "ab")); | 548 base::ScopedFILE file(base::OpenFile(filename, "ab")); |
| 549 const char buf[] = "im in ur base, killing ur d00dz."; | 549 const char buf[] = "im in ur base, killing ur d00dz."; |
| 550 ASSERT_EQ(strlen(buf), fwrite(buf, 1, strlen(buf), file.get())); | 550 ASSERT_EQ(strlen(buf), fwrite(buf, 1, strlen(buf), file.get())); |
| 551 file.reset(); | 551 file.reset(); |
| 552 scoped_ptr<PrefixSet> prefix_set = PrefixSet::LoadFile(filename); | 552 scoped_ptr<const PrefixSet> prefix_set = PrefixSet::LoadFile(filename); |
| 553 ASSERT_FALSE(prefix_set.get()); | 553 ASSERT_FALSE(prefix_set.get()); |
| 554 } | 554 } |
| 555 | 555 |
| 556 // Test that files which had 64-bit size_t are discarded. | 556 // Test that files which had 64-bit size_t are discarded. |
| 557 TEST_F(PrefixSetTest, SizeTRecovery) { | 557 TEST_F(PrefixSetTest, SizeTRecovery) { |
| 558 base::FilePath filename; | 558 base::FilePath filename; |
| 559 ASSERT_TRUE(GetPrefixSetFile(&filename)); | 559 ASSERT_TRUE(GetPrefixSetFile(&filename)); |
| 560 | 560 |
| 561 // Open the file for rewrite. | 561 // Open the file for rewrite. |
| 562 base::ScopedFILE file(base::OpenFile(filename, "r+b")); | 562 base::ScopedFILE file(base::OpenFile(filename, "r+b")); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 584 ASSERT_EQ(sizeof(delta), fwrite(&delta, 1, sizeof(delta), file.get())); | 584 ASSERT_EQ(sizeof(delta), fwrite(&delta, 1, sizeof(delta), file.get())); |
| 585 ASSERT_EQ(sizeof(delta), fwrite(&delta, 1, sizeof(delta), file.get())); | 585 ASSERT_EQ(sizeof(delta), fwrite(&delta, 1, sizeof(delta), file.get())); |
| 586 | 586 |
| 587 // Leave space for the digest at the end, and regenerate it. | 587 // Leave space for the digest at the end, and regenerate it. |
| 588 base::MD5Digest dummy = { { 0 } }; | 588 base::MD5Digest dummy = { { 0 } }; |
| 589 ASSERT_EQ(sizeof(dummy), fwrite(&dummy, 1, sizeof(dummy), file.get())); | 589 ASSERT_EQ(sizeof(dummy), fwrite(&dummy, 1, sizeof(dummy), file.get())); |
| 590 ASSERT_TRUE(base::TruncateFile(file.get())); | 590 ASSERT_TRUE(base::TruncateFile(file.get())); |
| 591 CleanChecksum(file.get()); | 591 CleanChecksum(file.get()); |
| 592 file.reset(); // Flush updates. | 592 file.reset(); // Flush updates. |
| 593 | 593 |
| 594 scoped_ptr<PrefixSet> prefix_set = PrefixSet::LoadFile(filename); | 594 scoped_ptr<const PrefixSet> prefix_set = PrefixSet::LoadFile(filename); |
| 595 ASSERT_FALSE(prefix_set.get()); | 595 ASSERT_FALSE(prefix_set.get()); |
| 596 } | 596 } |
| 597 | 597 |
| 598 // Test Exists() against full hashes passed to builder. | 598 // Test Exists() against full hashes passed to builder. |
| 599 TEST_F(PrefixSetTest, FullHashBuild) { | 599 TEST_F(PrefixSetTest, FullHashBuild) { |
| 600 const SBFullHash kHash1 = SBFullHashForString("one"); | 600 const SBFullHash kHash1 = SBFullHashForString("one"); |
| 601 const SBFullHash kHash2 = SBFullHashForString("two"); | 601 const SBFullHash kHash2 = SBFullHashForString("two"); |
| 602 const SBFullHash kHash3 = SBFullHashForString("three"); | 602 const SBFullHash kHash3 = SBFullHashForString("three"); |
| 603 const SBFullHash kHash4 = SBFullHashForString("four"); | 603 const SBFullHash kHash4 = SBFullHashForString("four"); |
| 604 const SBFullHash kHash5 = SBFullHashForString("five"); | 604 const SBFullHash kHash5 = SBFullHashForString("five"); |
| 605 const SBFullHash kHash6 = SBFullHashForString("six"); | 605 const SBFullHash kHash6 = SBFullHashForString("six"); |
| 606 | 606 |
| 607 std::vector<SBPrefix> prefixes; | 607 std::vector<SBPrefix> prefixes; |
| 608 prefixes.push_back(kHash1.prefix); | 608 prefixes.push_back(kHash1.prefix); |
| 609 prefixes.push_back(kHash2.prefix); | 609 prefixes.push_back(kHash2.prefix); |
| 610 std::sort(prefixes.begin(), prefixes.end()); | 610 std::sort(prefixes.begin(), prefixes.end()); |
| 611 | 611 |
| 612 std::vector<SBFullHash> hashes; | 612 std::vector<SBFullHash> hashes; |
| 613 hashes.push_back(kHash4); | 613 hashes.push_back(kHash4); |
| 614 hashes.push_back(kHash5); | 614 hashes.push_back(kHash5); |
| 615 | 615 |
| 616 PrefixSetBuilder builder(prefixes); | 616 PrefixSetBuilder builder(prefixes); |
| 617 scoped_ptr<PrefixSet> prefix_set = builder.GetPrefixSet(hashes); | 617 scoped_ptr<const PrefixSet> prefix_set = builder.GetPrefixSet(hashes); |
| 618 | 618 |
| 619 EXPECT_TRUE(prefix_set->Exists(kHash1)); | 619 EXPECT_TRUE(prefix_set->Exists(kHash1)); |
| 620 EXPECT_TRUE(prefix_set->Exists(kHash2)); | 620 EXPECT_TRUE(prefix_set->Exists(kHash2)); |
| 621 EXPECT_FALSE(prefix_set->Exists(kHash3)); | 621 EXPECT_FALSE(prefix_set->Exists(kHash3)); |
| 622 EXPECT_TRUE(prefix_set->Exists(kHash4)); | 622 EXPECT_TRUE(prefix_set->Exists(kHash4)); |
| 623 EXPECT_TRUE(prefix_set->Exists(kHash5)); | 623 EXPECT_TRUE(prefix_set->Exists(kHash5)); |
| 624 EXPECT_FALSE(prefix_set->Exists(kHash6)); | 624 EXPECT_FALSE(prefix_set->Exists(kHash6)); |
| 625 | 625 |
| 626 EXPECT_TRUE(prefix_set->PrefixExists(kHash1.prefix)); | 626 EXPECT_TRUE(prefix_set->PrefixExists(kHash1.prefix)); |
| 627 EXPECT_TRUE(prefix_set->PrefixExists(kHash2.prefix)); | 627 EXPECT_TRUE(prefix_set->PrefixExists(kHash2.prefix)); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 665 ASSERT_EQ(sizeof(delta), fwrite(&delta, 1, sizeof(delta), file.get())); | 665 ASSERT_EQ(sizeof(delta), fwrite(&delta, 1, sizeof(delta), file.get())); |
| 666 ASSERT_EQ(sizeof(delta), fwrite(&delta, 1, sizeof(delta), file.get())); | 666 ASSERT_EQ(sizeof(delta), fwrite(&delta, 1, sizeof(delta), file.get())); |
| 667 | 667 |
| 668 // Leave space for the digest at the end, and regenerate it. | 668 // Leave space for the digest at the end, and regenerate it. |
| 669 base::MD5Digest dummy = { { 0 } }; | 669 base::MD5Digest dummy = { { 0 } }; |
| 670 ASSERT_EQ(sizeof(dummy), fwrite(&dummy, 1, sizeof(dummy), file.get())); | 670 ASSERT_EQ(sizeof(dummy), fwrite(&dummy, 1, sizeof(dummy), file.get())); |
| 671 ASSERT_TRUE(base::TruncateFile(file.get())); | 671 ASSERT_TRUE(base::TruncateFile(file.get())); |
| 672 CleanChecksum(file.get()); | 672 CleanChecksum(file.get()); |
| 673 file.reset(); // Flush updates. | 673 file.reset(); // Flush updates. |
| 674 | 674 |
| 675 scoped_ptr<safe_browsing::PrefixSet> | 675 scoped_ptr<const PrefixSet> prefix_set = PrefixSet::LoadFile(filename); |
| 676 prefix_set(safe_browsing::PrefixSet::LoadFile(filename)); | |
| 677 ASSERT_FALSE(prefix_set.get()); | 676 ASSERT_FALSE(prefix_set.get()); |
| 678 } | 677 } |
| 679 | 678 |
| 680 // Test that a golden v2 file is discarded on read. All platforms generating v2 | 679 // Test that a golden v2 file is discarded on read. All platforms generating v2 |
| 681 // files are little-endian, so there is no point to testing this transition | 680 // files are little-endian, so there is no point to testing this transition |
| 682 // if/when a big-endian port is added. | 681 // if/when a big-endian port is added. |
| 683 #if defined(ARCH_CPU_LITTLE_ENDIAN) | 682 #if defined(ARCH_CPU_LITTLE_ENDIAN) |
| 684 TEST_F(PrefixSetTest, Version2) { | 683 TEST_F(PrefixSetTest, Version2) { |
| 685 std::vector<SBPrefix> ref_prefixes; | 684 std::vector<SBPrefix> ref_prefixes; |
| 686 ASSERT_TRUE(ReadReferencePrefixes(&ref_prefixes)); | 685 ASSERT_TRUE(ReadReferencePrefixes(&ref_prefixes)); |
| 687 | 686 |
| 688 const char kBasename[] = "PrefixSetVersion2"; | 687 const char kBasename[] = "PrefixSetVersion2"; |
| 689 base::FilePath golden_path; | 688 base::FilePath golden_path; |
| 690 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &golden_path)); | 689 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &golden_path)); |
| 691 golden_path = golden_path.AppendASCII("SafeBrowsing"); | 690 golden_path = golden_path.AppendASCII("SafeBrowsing"); |
| 692 golden_path = golden_path.AppendASCII(kBasename); | 691 golden_path = golden_path.AppendASCII(kBasename); |
| 693 | 692 |
| 694 scoped_ptr<PrefixSet> prefix_set = PrefixSet::LoadFile(golden_path); | 693 scoped_ptr<const PrefixSet> prefix_set(PrefixSet::LoadFile(golden_path)); |
| 695 ASSERT_FALSE(prefix_set.get()); | 694 ASSERT_FALSE(prefix_set.get()); |
| 696 } | 695 } |
| 697 #endif | 696 #endif |
| 698 | 697 |
| 699 // Test that a golden v3 file can be read by the current code. All platforms | 698 // Test that a golden v3 file can be read by the current code. All platforms |
| 700 // generating v3 files are little-endian, so there is no point to testing this | 699 // generating v3 files are little-endian, so there is no point to testing this |
| 701 // transition if/when a big-endian port is added. | 700 // transition if/when a big-endian port is added. |
| 702 #if defined(ARCH_CPU_LITTLE_ENDIAN) | 701 #if defined(ARCH_CPU_LITTLE_ENDIAN) |
| 703 TEST_F(PrefixSetTest, Version3) { | 702 TEST_F(PrefixSetTest, Version3) { |
| 704 std::vector<SBPrefix> ref_prefixes; | 703 std::vector<SBPrefix> ref_prefixes; |
| 705 ASSERT_TRUE(ReadReferencePrefixes(&ref_prefixes)); | 704 ASSERT_TRUE(ReadReferencePrefixes(&ref_prefixes)); |
| 706 | 705 |
| 707 const char kBasename[] = "PrefixSetVersion3"; | 706 const char kBasename[] = "PrefixSetVersion3"; |
| 708 base::FilePath golden_path; | 707 base::FilePath golden_path; |
| 709 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &golden_path)); | 708 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &golden_path)); |
| 710 golden_path = golden_path.AppendASCII("SafeBrowsing"); | 709 golden_path = golden_path.AppendASCII("SafeBrowsing"); |
| 711 golden_path = golden_path.AppendASCII(kBasename); | 710 golden_path = golden_path.AppendASCII(kBasename); |
| 712 | 711 |
| 713 scoped_ptr<PrefixSet> prefix_set = PrefixSet::LoadFile(golden_path); | 712 scoped_ptr<const PrefixSet> prefix_set(PrefixSet::LoadFile(golden_path)); |
| 714 ASSERT_TRUE(prefix_set.get()); | 713 ASSERT_TRUE(prefix_set.get()); |
| 715 CheckPrefixes(*prefix_set, ref_prefixes); | 714 CheckPrefixes(*prefix_set, ref_prefixes); |
| 716 | 715 |
| 717 const SBFullHash kHash1 = SBFullHashForString("www.evil.com/malware.html"); | 716 const SBFullHash kHash1 = SBFullHashForString("www.evil.com/malware.html"); |
| 718 const SBFullHash kHash2 = SBFullHashForString("www.evil.com/phishing.html"); | 717 const SBFullHash kHash2 = SBFullHashForString("www.evil.com/phishing.html"); |
| 719 | 718 |
| 720 EXPECT_TRUE(prefix_set->Exists(kHash1)); | 719 EXPECT_TRUE(prefix_set->Exists(kHash1)); |
| 721 EXPECT_TRUE(prefix_set->Exists(kHash2)); | 720 EXPECT_TRUE(prefix_set->Exists(kHash2)); |
| 722 EXPECT_FALSE(prefix_set->PrefixExists(kHash1.prefix)); | 721 EXPECT_FALSE(prefix_set->PrefixExists(kHash1.prefix)); |
| 723 EXPECT_FALSE(prefix_set->PrefixExists(kHash2.prefix)); | 722 EXPECT_FALSE(prefix_set->PrefixExists(kHash2.prefix)); |
| 724 } | 723 } |
| 725 #endif | 724 #endif |
| 726 | 725 |
| 727 } // namespace safe_browsing | 726 } // namespace safe_browsing |
| OLD | NEW |