Chromium Code Reviews| Index: content/browser/download/base_file.cc |
| diff --git a/content/browser/download/base_file.cc b/content/browser/download/base_file.cc |
| index 59dfa839cd51dca2373f2b6204d5a64c418fb41c..f4afd4addf655384f9248623b85d91344f65a00c 100644 |
| --- a/content/browser/download/base_file.cc |
| +++ b/content/browser/download/base_file.cc |
| @@ -44,7 +44,8 @@ DownloadInterruptReason BaseFile::Initialize( |
| base::File file, |
| int64_t bytes_so_far, |
| const std::string& hash_so_far, |
| - std::unique_ptr<crypto::SecureHash> hash_state) { |
| + std::unique_ptr<crypto::SecureHash> hash_state, |
| + AccessMode access_mode) { |
| DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
| DCHECK(!detached_); |
| @@ -70,6 +71,8 @@ DownloadInterruptReason BaseFile::Initialize( |
| bytes_so_far_ = bytes_so_far; |
| secure_hash_ = std::move(hash_state); |
| + access_mode_ = access_mode; |
| + DCHECK(access_mode_ == EXCLUSIVE || !secure_hash_); |
| file_ = std::move(file); |
| return Open(hash_so_far); |
| @@ -77,9 +80,24 @@ DownloadInterruptReason BaseFile::Initialize( |
| DownloadInterruptReason BaseFile::AppendDataToFile(const char* data, |
| size_t data_len) { |
| - DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
| - DCHECK(!detached_); |
| + DCHECK_EQ(access_mode_, EXCLUSIVE); |
| + return WriteAtCurrentPos(data, data_len); |
| +} |
| + |
| +DownloadInterruptReason BaseFile::WriteDataToFile(int64_t offset, |
| + const char* data, |
| + size_t data_len) { |
| + DCHECK_EQ(access_mode_, SHARED); |
| + |
| + if (file_.Seek(base::File::FROM_BEGIN, offset) < 0) { |
|
asanka
2017/02/16 18:11:24
base::File::Write() can be used to write to a spec
asanka
2017/02/16 18:46:25
Disregard.
qinmin
2017/02/16 21:35:50
I used this seek() to reuse some of code from Appe
asanka
2017/02/16 21:58:02
Probably because this code predates the logic in b
qinmin
2017/02/16 22:20:29
Done. Removed the while loop around the Write() ca
|
| + logging::SystemErrorCode error = logging::GetLastSystemErrorCode(); |
| + return LogSystemError("Unable to seek", error); |
| + } |
| + return WriteAtCurrentPos(data, data_len); |
| +} |
| +DownloadInterruptReason BaseFile::WriteAtCurrentPos(const char* data, |
| + size_t data_len) { |
| // NOTE(benwells): The above DCHECK won't be present in release builds, |
| // so we log any occurences to see how common this error is in the wild. |
| if (detached_) |
| @@ -288,6 +306,16 @@ DownloadInterruptReason BaseFile::Open(const std::string& hash_so_far) { |
| net::NetLogEventType::DOWNLOAD_FILE_OPENED, |
| base::Bind(&FileOpenedNetLogCallback, &full_path_, bytes_so_far_)); |
| + // For SHARED file, skip hash validation. |
| + if (access_mode_ == SHARED) { |
| + if (file_.GetLength() < bytes_so_far_) { |
| + ClearFile(); |
| + return LogInterruptReason("File has fewer written bytes than expected", 0, |
| + DOWNLOAD_INTERRUPT_REASON_FILE_TOO_SHORT); |
| + } |
| + return DOWNLOAD_INTERRUPT_REASON_NONE; |
| + } |
| + |
| if (!secure_hash_) { |
| DownloadInterruptReason reason = CalculatePartialHash(hash_so_far); |
| if (reason != DOWNLOAD_INTERRUPT_REASON_NONE) { |