diff options
author | aedla@chromium.org <aedla@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-01-31 17:30:39 +0000 |
---|---|---|
committer | aedla@chromium.org <aedla@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-01-31 17:30:39 +0000 |
commit | 811f3cdb481f280a40ca6c3a4df38c78007fc654 (patch) | |
tree | 635783220e00a74313c30e7cfed0a4ca23f6494d /webkit | |
parent | 67f74a17819e7c2765296f5a1ccc806ad7682dd7 (diff) | |
download | chromium_src-811f3cdb481f280a40ca6c3a4df38c78007fc654.zip chromium_src-811f3cdb481f280a40ca6c3a4df38c78007fc654.tar.gz chromium_src-811f3cdb481f280a40ca6c3a4df38c78007fc654.tar.bz2 |
Avoid integer overflows in BlobURLRequestJob.
BUG=169685
Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=179154
Review URL: https://chromiumcodereview.appspot.com/12047012
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@179901 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit')
-rw-r--r-- | webkit/blob/blob_url_request_job.cc | 69 | ||||
-rw-r--r-- | webkit/blob/blob_url_request_job.h | 1 |
2 files changed, 51 insertions, 19 deletions
diff --git a/webkit/blob/blob_url_request_job.cc b/webkit/blob/blob_url_request_job.cc index ae3dd24..c9aefe4 100644 --- a/webkit/blob/blob_url_request_job.cc +++ b/webkit/blob/blob_url_request_job.cc @@ -4,6 +4,9 @@ #include "webkit/blob/blob_url_request_job.h" +#include <limits> + +#include "base/basictypes.h" #include "base/bind.h" #include "base/compiler_specific.h" #include "base/files/file_util_proxy.h" @@ -183,6 +186,19 @@ void BlobURLRequestJob::DidStart() { CountSize(); } +bool BlobURLRequestJob::AddItemLength(size_t index, int64 item_length) { + if (item_length > kint64max - total_size_) { + 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 +214,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 +266,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 +447,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) { diff --git a/webkit/blob/blob_url_request_job.h b/webkit/blob/blob_url_request_job.h index 437dd3b..e24a491 100644 --- a/webkit/blob/blob_url_request_job.h +++ b/webkit/blob/blob_url_request_job.h @@ -60,6 +60,7 @@ class WEBKIT_STORAGE_EXPORT BlobURLRequestJob : public net::URLRequestJob { // For preparing for read: get the size, apply the range and perform seek. void DidStart(); + bool AddItemLength(size_t index, int64 item_length); void CountSize(); void DidCountSize(int error); void DidGetFileItemLength(size_t index, int64 result); |