diff options
-rw-r--r-- | chrome/browser/download/chrome_download_manager_delegate.cc | 8 | ||||
-rw-r--r-- | chrome/browser/download/chrome_download_manager_delegate.h | 3 | ||||
-rw-r--r-- | chrome/browser/download/download_item_unittest.cc | 2 | ||||
-rw-r--r-- | content/browser/download/base_file.cc | 14 | ||||
-rw-r--r-- | content/browser/download/base_file.h | 8 | ||||
-rw-r--r-- | content/browser/download/base_file_unittest.cc | 10 | ||||
-rw-r--r-- | content/browser/download/download_file_manager.cc | 3 | ||||
-rw-r--r-- | content/browser/download/download_item.cc | 5 | ||||
-rw-r--r-- | content/browser/download/download_item.h | 12 | ||||
-rw-r--r-- | content/browser/download/download_manager.cc | 5 | ||||
-rw-r--r-- | content/browser/download/mock_download_manager_delegate.cc | 3 | ||||
-rw-r--r-- | content/browser/download/mock_download_manager_delegate.h | 3 | ||||
-rw-r--r-- | content/browser/download/save_package.cc | 3 | ||||
-rw-r--r-- | content/public/browser/download_manager_delegate.h | 6 | ||||
-rw-r--r-- | content/shell/shell_download_manager_delegate.cc | 4 | ||||
-rw-r--r-- | content/shell/shell_download_manager_delegate.h | 3 |
16 files changed, 58 insertions, 34 deletions
diff --git a/chrome/browser/download/chrome_download_manager_delegate.cc b/chrome/browser/download/chrome_download_manager_delegate.cc index deaa40c..b7b4af6 100644 --- a/chrome/browser/download/chrome_download_manager_delegate.cc +++ b/chrome/browser/download/chrome_download_manager_delegate.cc @@ -200,14 +200,12 @@ bool ChromeDownloadManagerDelegate::GenerateFileHash() { #endif } -void ChromeDownloadManagerDelegate::OnResponseCompleted( - DownloadItem* item, - const std::string& hash) { +void ChromeDownloadManagerDelegate::OnResponseCompleted(DownloadItem* item) { #if defined(ENABLE_SAFE_BROWSING) // When hash is not available, it means either it is not calculated // or there is error while it is calculated. We will skip the download hash // check in that case. - if (hash.empty()) + if (item->hash().empty()) return; scoped_refptr<DownloadSBClient> sb_client = @@ -217,7 +215,7 @@ void ChromeDownloadManagerDelegate::OnResponseCompleted( profile_->GetPrefs()->GetBoolean( prefs::kSafeBrowsingEnabled)); sb_client->CheckDownloadHash( - hash, + item->hash(), base::Bind(&ChromeDownloadManagerDelegate::CheckDownloadHashDone, base::Unretained(this))); #endif diff --git a/chrome/browser/download/chrome_download_manager_delegate.h b/chrome/browser/download/chrome_download_manager_delegate.h index ffc486d..c5c4007 100644 --- a/chrome/browser/download/chrome_download_manager_delegate.h +++ b/chrome/browser/download/chrome_download_manager_delegate.h @@ -62,8 +62,7 @@ class ChromeDownloadManagerDelegate virtual bool ShouldCompleteDownload(DownloadItem* item) OVERRIDE; virtual bool ShouldOpenDownload(DownloadItem* item) OVERRIDE; virtual bool GenerateFileHash() OVERRIDE; - virtual void OnResponseCompleted(DownloadItem* item, - const std::string& hash) OVERRIDE; + virtual void OnResponseCompleted(DownloadItem* item) OVERRIDE; virtual void AddItemToPersistentStore(DownloadItem* item) OVERRIDE; virtual void UpdateItemInPersistentStore(DownloadItem* item) OVERRIDE; virtual void UpdatePathForItemInPersistentStore( diff --git a/chrome/browser/download/download_item_unittest.cc b/chrome/browser/download/download_item_unittest.cc index 45f634b..85edae9 100644 --- a/chrome/browser/download/download_item_unittest.cc +++ b/chrome/browser/download/download_item_unittest.cc @@ -147,7 +147,7 @@ TEST_F(DownloadItemTest, NotificationAfterComplete) { MockObserver observer(item); // Calling OnAllDataSaved does not trigger notification - item->OnAllDataSaved(kDownloadChunkSize); + item->OnAllDataSaved(kDownloadChunkSize, DownloadItem::kEmptyFileHash); ASSERT_FALSE(observer.CheckUpdated()); item->MarkAsComplete(); diff --git a/content/browser/download/base_file.cc b/content/browser/download/base_file.cc index c343cea..5112100 100644 --- a/content/browser/download/base_file.cc +++ b/content/browser/download/base_file.cc @@ -186,6 +186,9 @@ net::Error RenameFileAndResetSecurityDescriptor( } // namespace +// This will initialize the entire array to zero. +const unsigned char BaseFile::kEmptySha256Hash[] = { 0 }; + BaseFile::BaseFile(const FilePath& full_path, const GURL& source_url, const GURL& referrer_url, @@ -200,7 +203,7 @@ BaseFile::BaseFile(const FilePath& full_path, calculate_hash_(false), detached_(false) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); - memset(sha256_hash_, 0, sizeof(sha256_hash_)); + memcpy(sha256_hash_, kEmptySha256Hash, kSha256HashLen); if (file_stream_.get()) file_stream_->EnableErrorStatistics(); } @@ -382,11 +385,14 @@ void BaseFile::Finish() { bool BaseFile::GetSha256Hash(std::string* hash) { DCHECK(!detached_); - if (!calculate_hash_ || in_progress()) - return false; hash->assign(reinterpret_cast<const char*>(sha256_hash_), sizeof(sha256_hash_)); - return true; + return (calculate_hash_ && !in_progress()); +} + +bool BaseFile::IsEmptySha256Hash(const std::string& hash) { + return (hash.size() == kSha256HashLen && + 0 == memcmp(hash.data(), kEmptySha256Hash, sizeof(kSha256HashLen))); } void BaseFile::AnnotateWithSourceInformation() { diff --git a/content/browser/download/base_file.h b/content/browser/download/base_file.h index 7076ef1..8fbcdd0 100644 --- a/content/browser/download/base_file.h +++ b/content/browser/download/base_file.h @@ -9,6 +9,7 @@ #include <string> #include "base/file_path.h" +#include "base/gtest_prod_util.h" #include "base/memory/linked_ptr.h" #include "base/memory/scoped_ptr.h" #include "content/browser/power_save_blocker.h" @@ -67,6 +68,11 @@ class CONTENT_EXPORT BaseFile { // Returns true if digest is successfully calculated. virtual bool GetSha256Hash(std::string* hash); + // Returns true if the given hash is considered empty. An empty hash is + // a string of size kSha256HashLen that contains only zeros (initial value + // for the hash). + static bool IsEmptySha256Hash(const std::string& hash); + virtual std::string DebugString() const; protected: @@ -81,8 +87,10 @@ class CONTENT_EXPORT BaseFile { private: friend class BaseFileTest; friend class DownloadFileWithMockStream; + FRIEND_TEST_ALL_PREFIXES(BaseFileTest, IsEmptySha256Hash); static const size_t kSha256HashLen = 32; + static const unsigned char kEmptySha256Hash[kSha256HashLen]; // Source URL for the file being downloaded. GURL source_url_; diff --git a/content/browser/download/base_file_unittest.cc b/content/browser/download/base_file_unittest.cc index df80e24..6d6edc7 100644 --- a/content/browser/download/base_file_unittest.cc +++ b/content/browser/download/base_file_unittest.cc @@ -30,6 +30,8 @@ const int kTestDataLength2 = arraysize(kTestData2) - 1; const int kTestDataLength3 = arraysize(kTestData3) - 1; const int kTestDataLength4 = arraysize(kTestData4) - 1; +} // namespace + class BaseFileTest : public testing::Test { public: BaseFileTest() @@ -403,4 +405,10 @@ TEST_F(BaseFileTest, ReadonlyBaseFile) { expect_file_survives_ = true; } -} // namespace +TEST_F(BaseFileTest, IsEmptySha256Hash) { + std::string empty(BaseFile::kSha256HashLen, '\x00'); + EXPECT_TRUE(BaseFile::IsEmptySha256Hash(empty)); + std::string not_empty(BaseFile::kSha256HashLen, '\x01'); + EXPECT_FALSE(BaseFile::IsEmptySha256Hash(not_empty)); + EXPECT_FALSE(BaseFile::IsEmptySha256Hash("")); +} diff --git a/content/browser/download/download_file_manager.cc b/content/browser/download/download_file_manager.cc index 755e6e9..97a4280 100644 --- a/content/browser/download/download_file_manager.cc +++ b/content/browser/download/download_file_manager.cc @@ -12,6 +12,7 @@ #include "base/logging.h" #include "base/stl_util.h" #include "base/utf_string_conversions.h" +#include "content/browser/download/base_file.h" #include "content/browser/download/download_buffer.h" #include "content/browser/download/download_create_info.h" #include "content/browser/download/download_file.h" @@ -214,7 +215,7 @@ void DownloadFileManager::OnResponseCompleted( } std::string hash; - if (!download_file->GetSha256Hash(&hash)) + if (!download_file->GetSha256Hash(&hash) || BaseFile::IsEmptySha256Hash(hash)) hash.clear(); if (reason == DOWNLOAD_INTERRUPT_REASON_NONE) { diff --git a/content/browser/download/download_item.cc b/content/browser/download/download_item.cc index 34492af..e3eff99 100644 --- a/content/browser/download/download_item.cc +++ b/content/browser/download/download_item.cc @@ -119,6 +119,8 @@ DownloadItem::DangerType GetDangerType(bool dangerous_file, // static const int DownloadItem::kUninitializedHandle = 0; +const char DownloadItem::kEmptyFileHash[] = ""; + // Constructor for reading from the history service. DownloadItem::DownloadItem(DownloadManager* download_manager, const DownloadPersistentStoreInfo& info) @@ -382,13 +384,14 @@ void DownloadItem::DelayedDownloadOpened() { Completed(); } -void DownloadItem::OnAllDataSaved(int64 size) { +void DownloadItem::OnAllDataSaved(int64 size, const std::string& final_hash) { // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(!all_data_saved_); all_data_saved_ = true; UpdateSize(size); + hash_ = final_hash; } void DownloadItem::OnDownloadedFileRemoved() { diff --git a/content/browser/download/download_item.h b/content/browser/download/download_item.h index 035510f..3d3b0e7 100644 --- a/content/browser/download/download_item.h +++ b/content/browser/download/download_item.h @@ -102,6 +102,8 @@ class CONTENT_EXPORT DownloadItem { // but is not yet in the table. static const int kUninitializedHandle; + static const char kEmptyFileHash[]; + // Interface that observers of a particular download must implement in order // to receive updates to the download's status. class CONTENT_EXPORT Observer { @@ -183,8 +185,8 @@ class CONTENT_EXPORT DownloadItem { // DownloadManagerDelegate::ShouldOpenDownload. void DelayedDownloadOpened(); - // Called when all data has been saved. Only has display effects. - void OnAllDataSaved(int64 size); + // Called when all data has been saved. + void OnAllDataSaved(int64 size, const std::string& final_hash); // Called when the downloaded file is removed. void OnDownloadedFileRemoved(); @@ -281,6 +283,7 @@ class CONTENT_EXPORT DownloadItem { total_bytes_ = total_bytes; } int64 received_bytes() const { return received_bytes_; } + const std::string& hash() const { return hash_; } int32 id() const { return download_id_.local(); } DownloadId global_id() const { return download_id_; } base::Time start_time() const { return start_time_; } @@ -420,6 +423,11 @@ class CONTENT_EXPORT DownloadItem { // Current received bytes int64 received_bytes_; + // Sha256 hash of the content. This might be empty either because + // the download isn't done yet or because the hash isn't needed + // (ChromeDownloadManagerDelegate::GenerateFileHash() returned false). + std::string hash_; + // Last reason. InterruptReason last_reason_; diff --git a/content/browser/download/download_manager.cc b/content/browser/download/download_manager.cc index e56a927..e80113e 100644 --- a/content/browser/download/download_manager.cc +++ b/content/browser/download/download_manager.cc @@ -394,9 +394,8 @@ void DownloadManager::OnResponseCompleted(int32 download_id, return; DownloadItem* download = active_downloads_[download_id]; - download->OnAllDataSaved(size); - - delegate_->OnResponseCompleted(download, hash); + download->OnAllDataSaved(size, hash); + delegate_->OnResponseCompleted(download); MaybeCompleteDownload(download); } diff --git a/content/browser/download/mock_download_manager_delegate.cc b/content/browser/download/mock_download_manager_delegate.cc index 205669b..4fc719c 100644 --- a/content/browser/download/mock_download_manager_delegate.cc +++ b/content/browser/download/mock_download_manager_delegate.cc @@ -57,8 +57,7 @@ bool MockDownloadManagerDelegate::GenerateFileHash() { return false; } -void MockDownloadManagerDelegate::OnResponseCompleted(DownloadItem* item, - const std::string& hash) { +void MockDownloadManagerDelegate::OnResponseCompleted(DownloadItem* item) { } void MockDownloadManagerDelegate::AddItemToPersistentStore(DownloadItem* item) { diff --git a/content/browser/download/mock_download_manager_delegate.h b/content/browser/download/mock_download_manager_delegate.h index 2b50b4f..5584138 100644 --- a/content/browser/download/mock_download_manager_delegate.h +++ b/content/browser/download/mock_download_manager_delegate.h @@ -28,8 +28,7 @@ class MockDownloadManagerDelegate : public content::DownloadManagerDelegate { virtual bool ShouldCompleteDownload(DownloadItem* item) OVERRIDE; virtual bool ShouldOpenDownload(DownloadItem* item) OVERRIDE; virtual bool GenerateFileHash() OVERRIDE; - virtual void OnResponseCompleted(DownloadItem* item, - const std::string& hash) OVERRIDE; + virtual void OnResponseCompleted(DownloadItem* item) OVERRIDE; virtual void AddItemToPersistentStore(DownloadItem* item) OVERRIDE; virtual void UpdateItemInPersistentStore(DownloadItem* item) OVERRIDE; virtual void UpdatePathForItemInPersistentStore( diff --git a/content/browser/download/save_package.cc b/content/browser/download/save_package.cc index a0dca3b..bc96e89 100644 --- a/content/browser/download/save_package.cc +++ b/content/browser/download/save_package.cc @@ -681,7 +681,8 @@ void SavePackage::Finish() { save_ids)); if (download_) { - download_->OnAllDataSaved(all_save_items_count_); + download_->OnAllDataSaved(all_save_items_count_, + DownloadItem::kEmptyFileHash); download_->MarkAsComplete(); FinalizeDownloadEntry(); } diff --git a/content/public/browser/download_manager_delegate.h b/content/public/browser/download_manager_delegate.h index 46d6d78..35c60cc 100644 --- a/content/public/browser/download_manager_delegate.h +++ b/content/public/browser/download_manager_delegate.h @@ -70,10 +70,8 @@ class DownloadManagerDelegate { // Returns true if we need to generate a binary hash for downloads. virtual bool GenerateFileHash() = 0; - // Informs the delegate that given download has finishd downloading, and gives - // it the hash (if it chose to compute it from GenerateFileHash()). - virtual void OnResponseCompleted(DownloadItem* item, - const std::string& hash) = 0; + // Informs the delegate that given download has finishd downloading. + virtual void OnResponseCompleted(DownloadItem* item) = 0; // Notifies the delegate that a new download item is created. The // DownloadManager waits for the delegate to add information about this diff --git a/content/shell/shell_download_manager_delegate.cc b/content/shell/shell_download_manager_delegate.cc index 0118914..718ae3b4 100644 --- a/content/shell/shell_download_manager_delegate.cc +++ b/content/shell/shell_download_manager_delegate.cc @@ -164,9 +164,7 @@ bool ShellDownloadManagerDelegate::GenerateFileHash() { return false; } -void ShellDownloadManagerDelegate::OnResponseCompleted( - DownloadItem* item, - const std::string& hash) { +void ShellDownloadManagerDelegate::OnResponseCompleted(DownloadItem* item) { } void ShellDownloadManagerDelegate::AddItemToPersistentStore( diff --git a/content/shell/shell_download_manager_delegate.h b/content/shell/shell_download_manager_delegate.h index 8dda1c8..55b4416 100644 --- a/content/shell/shell_download_manager_delegate.h +++ b/content/shell/shell_download_manager_delegate.h @@ -35,8 +35,7 @@ class ShellDownloadManagerDelegate virtual bool ShouldCompleteDownload(DownloadItem* item) OVERRIDE; virtual bool ShouldOpenDownload(DownloadItem* item) OVERRIDE; virtual bool GenerateFileHash() OVERRIDE; - virtual void OnResponseCompleted(DownloadItem* item, - const std::string& hash) OVERRIDE; + virtual void OnResponseCompleted(DownloadItem* item) OVERRIDE; virtual void AddItemToPersistentStore(DownloadItem* item) OVERRIDE; virtual void UpdateItemInPersistentStore(DownloadItem* item) OVERRIDE; virtual void UpdatePathForItemInPersistentStore( |