Chromium Code Reviews| Index: webkit/blob/blob_url_request_job.cc |
| diff --git a/webkit/blob/blob_url_request_job.cc b/webkit/blob/blob_url_request_job.cc |
| index ae3dd24c9961c6835c3159b1276ca28932b5df71..f67a0dd6364326b92a2f744a61958f272f591853 100644 |
| --- a/webkit/blob/blob_url_request_job.cc |
| +++ b/webkit/blob/blob_url_request_job.cc |
| @@ -4,6 +4,8 @@ |
| #include "webkit/blob/blob_url_request_job.h" |
| +#include <limits> |
| + |
| #include "base/bind.h" |
| #include "base/compiler_specific.h" |
| #include "base/files/file_util_proxy.h" |
| @@ -183,6 +185,19 @@ void BlobURLRequestJob::DidStart() { |
| CountSize(); |
| } |
| +bool BlobURLRequestJob::AddItemLength(size_t index, int64 item_length) { |
| + if (item_length > std::numeric_limits<int64>::max() - total_size_) { |
|
michaeln
2013/01/29 20:22:43
base/basictypes.h defines some constants like this
|
| + NotifyFailure(net::ERR_FAILED); |
| + return false; |
| + } |
| + |
| + // Cache the size and add it to the total size. |
| + DCHECK_LT(index, item_length_list_.size()); |
| + item_length_list_[index] = item_length; |
| + total_size_ += item_length; |
| + return true; |
| +} |
| + |
| void BlobURLRequestJob::CountSize() { |
| error_ = false; |
| pending_get_file_info_count_ = 0; |
| @@ -198,10 +213,9 @@ void BlobURLRequestJob::CountSize() { |
| weak_factory_.GetWeakPtr(), i)); |
| continue; |
| } |
| - // Cache the size and add it to the total size. |
| - int64 item_length = static_cast<int64>(item.length()); |
| - item_length_list_[i] = item_length; |
| - total_size_ += item_length; |
| + |
| + if (!AddItemLength(i, item.length())) |
| + return; |
| } |
| if (pending_get_file_info_count_ == 0) |
| @@ -251,16 +265,28 @@ void BlobURLRequestJob::DidGetFileItemLength(size_t index, int64 result) { |
| const BlobData::Item& item = blob_data_->items().at(index); |
| DCHECK(IsFileType(item.type())); |
| + uint64 file_length = result; |
| + uint64 item_offset = item.offset(); |
| + uint64 item_length = item.length(); |
| + |
| + if (item_offset > file_length) { |
| + NotifyFailure(net::ERR_FILE_NOT_FOUND); |
| + return; |
| + } |
| + |
| + uint64 max_length = file_length - item_offset; |
| + |
| // If item length is -1, we need to use the file size being resolved |
| // in the real time. |
| - int64 item_length = static_cast<int64>(item.length()); |
| - if (item_length == -1) |
| - item_length = result - item.offset(); |
| + if (item_length == static_cast<uint64>(-1)) { |
| + item_length = max_length; |
| + } else if (item_length > max_length) { |
| + NotifyFailure(net::ERR_FILE_NOT_FOUND); |
| + return; |
| + } |
| - // Cache the size and add it to the total size. |
| - DCHECK_LT(index, item_length_list_.size()); |
| - item_length_list_[index] = item_length; |
| - total_size_ += item_length; |
| + if (!AddItemLength(index, item_length)) |
| + return; |
| if (--pending_get_file_info_count_ == 0) |
| DidCountSize(net::OK); |
| @@ -420,14 +446,18 @@ int BlobURLRequestJob::BytesReadCompleted() { |
| } |
| int BlobURLRequestJob::ComputeBytesToRead() const { |
| - int64 current_item_remaining_bytes = |
| - item_length_list_[current_item_index_] - current_item_offset_; |
| - int64 remaining_bytes = std::min(current_item_remaining_bytes, |
| - remaining_bytes_); |
| - |
| - return static_cast<int>(std::min( |
| - static_cast<int64>(read_buf_->BytesRemaining()), |
| - remaining_bytes)); |
| + int64 current_item_length = item_length_list_[current_item_index_]; |
| + |
| + int64 item_remaining = current_item_length - current_item_offset_; |
| + int64 buf_remaining = read_buf_->BytesRemaining(); |
| + int64 max_remaining = std::numeric_limits<int>::max(); |
| + |
| + int64 min = std::min(std::min(std::min(item_remaining, |
| + buf_remaining), |
| + remaining_bytes_), |
| + max_remaining); |
| + |
| + return static_cast<int>(min); |
| } |
| bool BlobURLRequestJob::ReadLoop(int* bytes_read) { |