| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 // This file should not be build on Android but is currently getting built. | 5 // This file should not be build on Android but is currently getting built. |
| 6 // TODO(vakh): Fix that: http://crbug.com/621647 | 6 // TODO(vakh): Fix that: http://crbug.com/621647 |
| 7 | 7 |
| 8 #include "components/safe_browsing_db/v4_local_database_manager.h" | 8 #include "components/safe_browsing_db/v4_local_database_manager.h" |
| 9 | 9 |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 153 } | 153 } |
| 154 | 154 |
| 155 // | 155 // |
| 156 // Start: SafeBrowsingDatabaseManager implementation | 156 // Start: SafeBrowsingDatabaseManager implementation |
| 157 // | 157 // |
| 158 | 158 |
| 159 void V4LocalDatabaseManager::CancelCheck(Client* client) { | 159 void V4LocalDatabaseManager::CancelCheck(Client* client) { |
| 160 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 160 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 161 DCHECK(enabled_); | 161 DCHECK(enabled_); |
| 162 | 162 |
| 163 auto it = pending_clients_.find(client); | 163 auto pending_it = std::find_if( |
| 164 if (it != pending_clients_.end()) { | 164 std::begin(pending_checks_), std::end(pending_checks_), |
| 165 pending_clients_.erase(it); | 165 [client](const PendingCheck* check) { return check->client == client; }); |
| 166 if (pending_it != pending_checks_.end()) { |
| 167 pending_checks_.erase(pending_it); |
| 166 } | 168 } |
| 167 | 169 |
| 168 auto queued_it = | 170 auto queued_it = |
| 169 std::find_if(std::begin(queued_checks_), std::end(queued_checks_), | 171 std::find_if(std::begin(queued_checks_), std::end(queued_checks_), |
| 170 [&client](const std::unique_ptr<PendingCheck>& check) { | 172 [&client](const std::unique_ptr<PendingCheck>& check) { |
| 171 return check->client == client; | 173 return check->client == client; |
| 172 }); | 174 }); |
| 173 if (queued_it != queued_checks_.end()) { | 175 if (queued_it != queued_checks_.end()) { |
| 174 queued_checks_.erase(queued_it); | 176 queued_checks_.erase(queued_it); |
| 175 } | 177 } |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 368 SetupDatabase(); | 370 SetupDatabase(); |
| 369 | 371 |
| 370 enabled_ = true; | 372 enabled_ = true; |
| 371 } | 373 } |
| 372 | 374 |
| 373 void V4LocalDatabaseManager::StopOnIOThread(bool shutdown) { | 375 void V4LocalDatabaseManager::StopOnIOThread(bool shutdown) { |
| 374 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 376 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 375 | 377 |
| 376 enabled_ = false; | 378 enabled_ = false; |
| 377 | 379 |
| 378 pending_clients_.clear(); | 380 pending_checks_.clear(); |
| 379 | 381 |
| 380 RespondSafeToQueuedChecks(); | 382 RespondSafeToQueuedChecks(); |
| 381 | 383 |
| 382 // Delete the V4Database. Any pending writes to disk are completed. | 384 // Delete the V4Database. Any pending writes to disk are completed. |
| 383 // This operation happens on the task_runner on which v4_database_ operates | 385 // This operation happens on the task_runner on which v4_database_ operates |
| 384 // and doesn't block the IO thread. | 386 // and doesn't block the IO thread. |
| 385 V4Database::Destroy(std::move(v4_database_)); | 387 V4Database::Destroy(std::move(v4_database_)); |
| 386 | 388 |
| 387 // Delete the V4UpdateProtocolManager. | 389 // Delete the V4UpdateProtocolManager. |
| 388 // This cancels any in-flight update request. | 390 // This cancels any in-flight update request. |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 527 if (!v4_database_) { | 529 if (!v4_database_) { |
| 528 queued_checks_.push_back(std::move(check)); | 530 queued_checks_.push_back(std::move(check)); |
| 529 return false; | 531 return false; |
| 530 } | 532 } |
| 531 | 533 |
| 532 FullHashToStoreAndHashPrefixesMap full_hash_to_store_and_hash_prefixes; | 534 FullHashToStoreAndHashPrefixesMap full_hash_to_store_and_hash_prefixes; |
| 533 if (!GetPrefixMatches(check, &full_hash_to_store_and_hash_prefixes)) { | 535 if (!GetPrefixMatches(check, &full_hash_to_store_and_hash_prefixes)) { |
| 534 return true; | 536 return true; |
| 535 } | 537 } |
| 536 | 538 |
| 539 // Add check to pending_checks_ before scheduling PerformFullHashCheck so that |
| 540 // even if the client calls CancelCheck before PerformFullHashCheck gets |
| 541 // called, the check can be found in pending_checks_. |
| 542 pending_checks_.insert(check.get()); |
| 543 |
| 537 // Post on the IO thread to enforce async behavior. | 544 // Post on the IO thread to enforce async behavior. |
| 538 pending_clients_.insert(check->client); | |
| 539 BrowserThread::PostTask( | 545 BrowserThread::PostTask( |
| 540 BrowserThread::IO, FROM_HERE, | 546 BrowserThread::IO, FROM_HERE, |
| 541 base::Bind(&V4LocalDatabaseManager::PerformFullHashCheck, this, | 547 base::Bind(&V4LocalDatabaseManager::PerformFullHashCheck, this, |
| 542 base::Passed(std::move(check)), | 548 base::Passed(std::move(check)), |
| 543 full_hash_to_store_and_hash_prefixes)); | 549 full_hash_to_store_and_hash_prefixes)); |
| 544 | 550 |
| 545 return false; | 551 return false; |
| 546 } | 552 } |
| 547 | 553 |
| 548 bool V4LocalDatabaseManager::HandleHashSynchronously( | 554 bool V4LocalDatabaseManager::HandleHashSynchronously( |
| (...skipping 16 matching lines...) Expand all Loading... |
| 565 | 571 |
| 566 std::unique_ptr<PendingCheck> check = base::MakeUnique<PendingCheck>( | 572 std::unique_ptr<PendingCheck> check = base::MakeUnique<PendingCheck>( |
| 567 nullptr, ClientCallbackType::CHECK_OTHER, stores_to_check, | 573 nullptr, ClientCallbackType::CHECK_OTHER, stores_to_check, |
| 568 std::vector<GURL>(1, url)); | 574 std::vector<GURL>(1, url)); |
| 569 | 575 |
| 570 FullHashToStoreAndHashPrefixesMap full_hash_to_store_and_hash_prefixes; | 576 FullHashToStoreAndHashPrefixesMap full_hash_to_store_and_hash_prefixes; |
| 571 return GetPrefixMatches(check, &full_hash_to_store_and_hash_prefixes); | 577 return GetPrefixMatches(check, &full_hash_to_store_and_hash_prefixes); |
| 572 } | 578 } |
| 573 | 579 |
| 574 void V4LocalDatabaseManager::OnFullHashResponse( | 580 void V4LocalDatabaseManager::OnFullHashResponse( |
| 575 std::unique_ptr<PendingCheck> pending_check, | 581 std::unique_ptr<PendingCheck> check, |
| 576 const std::vector<FullHashInfo>& full_hash_infos) { | 582 const std::vector<FullHashInfo>& full_hash_infos) { |
| 577 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 583 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 578 | 584 |
| 579 if (!enabled_) { | 585 if (!enabled_) { |
| 580 DCHECK(pending_clients_.empty()); | 586 DCHECK(pending_checks_.empty()); |
| 581 return; | 587 return; |
| 582 } | 588 } |
| 583 | 589 |
| 584 const auto it = pending_clients_.find(pending_check->client); | 590 const auto it = pending_checks_.find(check.get()); |
| 585 if (it == pending_clients_.end()) { | 591 if (it == pending_checks_.end()) { |
| 586 // The check has since been cancelled. | 592 // The check has since been cancelled. |
| 587 return; | 593 return; |
| 588 } | 594 } |
| 589 | 595 |
| 590 // Find out the most severe threat, if any, to report to the client. | 596 // Find out the most severe threat, if any, to report to the client. |
| 591 GetSeverestThreatTypeAndMetadata(&pending_check->result_threat_type, | 597 GetSeverestThreatTypeAndMetadata(&check->result_threat_type, |
| 592 &pending_check->url_metadata, | 598 &check->url_metadata, full_hash_infos); |
| 593 full_hash_infos); | 599 pending_checks_.erase(it); |
| 594 pending_clients_.erase(it); | 600 RespondToClient(std::move(check)); |
| 595 RespondToClient(std::move(pending_check)); | |
| 596 } | 601 } |
| 597 | 602 |
| 598 void V4LocalDatabaseManager::PerformFullHashCheck( | 603 void V4LocalDatabaseManager::PerformFullHashCheck( |
| 599 std::unique_ptr<PendingCheck> check, | 604 std::unique_ptr<PendingCheck> check, |
| 600 const FullHashToStoreAndHashPrefixesMap& | 605 const FullHashToStoreAndHashPrefixesMap& |
| 601 full_hash_to_store_and_hash_prefixes) { | 606 full_hash_to_store_and_hash_prefixes) { |
| 602 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 607 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 603 | 608 |
| 604 DCHECK(enabled_); | 609 DCHECK(enabled_); |
| 605 DCHECK(!full_hash_to_store_and_hash_prefixes.empty()); | 610 DCHECK(!full_hash_to_store_and_hash_prefixes.empty()); |
| 606 | 611 |
| 607 v4_get_hash_protocol_manager_->GetFullHashes( | 612 v4_get_hash_protocol_manager_->GetFullHashes( |
| 608 full_hash_to_store_and_hash_prefixes, | 613 full_hash_to_store_and_hash_prefixes, |
| 609 base::Bind(&V4LocalDatabaseManager::OnFullHashResponse, | 614 base::Bind(&V4LocalDatabaseManager::OnFullHashResponse, |
| 610 weak_factory_.GetWeakPtr(), base::Passed(std::move(check)))); | 615 weak_factory_.GetWeakPtr(), base::Passed(std::move(check)))); |
| 611 } | 616 } |
| 612 | 617 |
| 613 void V4LocalDatabaseManager::ProcessQueuedChecks() { | 618 void V4LocalDatabaseManager::ProcessQueuedChecks() { |
| 614 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 619 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 615 | 620 |
| 616 // Steal the queue to protect against reentrant CancelCheck() calls. | 621 // Steal the queue to protect against reentrant CancelCheck() calls. |
| 617 QueuedChecks checks; | 622 QueuedChecks checks; |
| 618 checks.swap(queued_checks_); | 623 checks.swap(queued_checks_); |
| 619 | 624 |
| 620 for (auto& it : checks) { | 625 for (auto& it : checks) { |
| 621 FullHashToStoreAndHashPrefixesMap full_hash_to_store_and_hash_prefixes; | 626 FullHashToStoreAndHashPrefixesMap full_hash_to_store_and_hash_prefixes; |
| 622 if (!GetPrefixMatches(it, &full_hash_to_store_and_hash_prefixes)) { | 627 if (!GetPrefixMatches(it, &full_hash_to_store_and_hash_prefixes)) { |
| 623 RespondToClient(std::move(it)); | 628 RespondToClient(std::move(it)); |
| 624 } else { | 629 } else { |
| 625 pending_clients_.insert(it->client); | 630 pending_checks_.insert(it.get()); |
| 626 PerformFullHashCheck(std::move(it), full_hash_to_store_and_hash_prefixes); | 631 PerformFullHashCheck(std::move(it), full_hash_to_store_and_hash_prefixes); |
| 627 } | 632 } |
| 628 } | 633 } |
| 629 } | 634 } |
| 630 | 635 |
| 631 void V4LocalDatabaseManager::RespondSafeToQueuedChecks() { | 636 void V4LocalDatabaseManager::RespondSafeToQueuedChecks() { |
| 632 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 637 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 633 | 638 |
| 634 // Steal the queue to protect against reentrant CancelCheck() calls. | 639 // Steal the queue to protect against reentrant CancelCheck() calls. |
| 635 QueuedChecks checks; | 640 QueuedChecks checks; |
| 636 checks.swap(queued_checks_); | 641 checks.swap(queued_checks_); |
| 637 | 642 |
| 638 for (std::unique_ptr<PendingCheck>& it : checks) { | 643 for (std::unique_ptr<PendingCheck>& it : checks) { |
| 639 RespondToClient(std::move(it)); | 644 RespondToClient(std::move(it)); |
| 640 } | 645 } |
| 641 } | 646 } |
| 642 | 647 |
| 643 void V4LocalDatabaseManager::RespondToClient( | 648 void V4LocalDatabaseManager::RespondToClient( |
| 644 std::unique_ptr<PendingCheck> check) { | 649 std::unique_ptr<PendingCheck> check) { |
| 645 DCHECK(check.get()); | 650 DCHECK(check.get()); |
| 646 | 651 |
| 647 if (check->client_callback_type == ClientCallbackType::CHECK_BROWSE_URL) { | 652 if (check->client_callback_type == ClientCallbackType::CHECK_BROWSE_URL) { |
| 648 DCHECK_EQ(1u, check->urls.size()); | 653 DCHECK_EQ(1u, check->urls.size()); |
| 649 // TODO(vakh): Remove these CHECKs after fixing bugs 660293, 660359. | |
| 650 CHECK(check.get()); | |
| 651 CHECK(check->client); | |
| 652 CHECK_LE(1u, check->urls.size()); | |
| 653 CHECK(check->urls[0].is_valid()); | |
| 654 check->client->OnCheckBrowseUrlResult( | 654 check->client->OnCheckBrowseUrlResult( |
| 655 check->urls[0], check->result_threat_type, check->url_metadata); | 655 check->urls[0], check->result_threat_type, check->url_metadata); |
| 656 } else if (check->client_callback_type == | 656 } else if (check->client_callback_type == |
| 657 ClientCallbackType::CHECK_DOWNLOAD_URLS) { | 657 ClientCallbackType::CHECK_DOWNLOAD_URLS) { |
| 658 check->client->OnCheckDownloadUrlResult(check->urls, | 658 check->client->OnCheckDownloadUrlResult(check->urls, |
| 659 check->result_threat_type); | 659 check->result_threat_type); |
| 660 } else if (check->client_callback_type == | 660 } else if (check->client_callback_type == |
| 661 ClientCallbackType::CHECK_EXTENSION_IDS) { | 661 ClientCallbackType::CHECK_EXTENSION_IDS) { |
| 662 const std::set<FullHash> extension_ids(check->full_hashes.begin(), | 662 const std::set<FullHash> extension_ids(check->full_hashes.begin(), |
| 663 check->full_hashes.end()); | 663 check->full_hashes.end()); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 707 db_updated_callback_); | 707 db_updated_callback_); |
| 708 } | 708 } |
| 709 | 709 |
| 710 bool V4LocalDatabaseManager::AreStoresAvailableNow( | 710 bool V4LocalDatabaseManager::AreStoresAvailableNow( |
| 711 const StoresToCheck& stores_to_check) const { | 711 const StoresToCheck& stores_to_check) const { |
| 712 return enabled_ && v4_database_ && | 712 return enabled_ && v4_database_ && |
| 713 v4_database_->AreStoresAvailable(stores_to_check); | 713 v4_database_->AreStoresAvailable(stores_to_check); |
| 714 } | 714 } |
| 715 | 715 |
| 716 } // namespace safe_browsing | 716 } // namespace safe_browsing |
| OLD | NEW |