| Index: content/browser/byte_stream.cc
|
| diff --git a/content/browser/byte_stream.cc b/content/browser/byte_stream.cc
|
| index a8b8f29e9e63b326229b8c09aa3818eefd98adbd..7b0f9fb0f9a792d5e1b6c21714879fba80743115 100644
|
| --- a/content/browser/byte_stream.cc
|
| +++ b/content/browser/byte_stream.cc
|
| @@ -61,6 +61,7 @@ class ByteStreamWriterImpl : public ByteStreamWriter {
|
| virtual void Flush() OVERRIDE;
|
| virtual void Close(int status) OVERRIDE;
|
| virtual void RegisterCallback(const base::Closure& source_callback) OVERRIDE;
|
| + virtual size_t GetTotalBufferedBytes() const OVERRIDE;
|
|
|
| // PostTask target from |ByteStreamReaderImpl::MaybeUpdateInput|.
|
| static void UpdateWindow(scoped_refptr<LifetimeFlag> lifetime_flag,
|
| @@ -209,6 +210,18 @@ bool ByteStreamWriterImpl::Write(
|
| scoped_refptr<net::IOBuffer> buffer, size_t byte_count) {
|
| DCHECK(my_task_runner_->RunsTasksOnCurrentThread());
|
|
|
| + // Check overflow.
|
| + //
|
| + // TODO(tyoshino): Discuss with content/browser/download developer and if
|
| + // they're fine with, set smaller limit and make it configurable.
|
| + size_t space_limit = std::numeric_limits<size_t>::max() -
|
| + GetTotalBufferedBytes();
|
| + if (byte_count > space_limit) {
|
| + // TODO(tyoshino): Tell the user that Write() failed.
|
| + // Ignore input.
|
| + return false;
|
| + }
|
| +
|
| input_contents_.push_back(std::make_pair(buffer, byte_count));
|
| input_contents_size_ += byte_count;
|
|
|
| @@ -216,7 +229,7 @@ bool ByteStreamWriterImpl::Write(
|
| if (input_contents_size_ > total_buffer_size_ / kFractionBufferBeforeSending)
|
| PostToPeer(false, 0);
|
|
|
| - return (input_contents_size_ + output_size_used_ <= total_buffer_size_);
|
| + return GetTotalBufferedBytes() <= total_buffer_size_;
|
| }
|
|
|
| void ByteStreamWriterImpl::Flush() {
|
| @@ -236,6 +249,13 @@ void ByteStreamWriterImpl::RegisterCallback(
|
| space_available_callback_ = source_callback;
|
| }
|
|
|
| +size_t ByteStreamWriterImpl::GetTotalBufferedBytes() const {
|
| + DCHECK(my_task_runner_->RunsTasksOnCurrentThread());
|
| + // This sum doesn't overflow since Write() fails if this sum is going to
|
| + // overflow.
|
| + return input_contents_size_ + output_size_used_;
|
| +}
|
| +
|
| // static
|
| void ByteStreamWriterImpl::UpdateWindow(
|
| scoped_refptr<LifetimeFlag> lifetime_flag, ByteStreamWriterImpl* target,
|
| @@ -248,15 +268,16 @@ void ByteStreamWriterImpl::UpdateWindow(
|
|
|
| void ByteStreamWriterImpl::UpdateWindowInternal(size_t bytes_consumed) {
|
| DCHECK(my_task_runner_->RunsTasksOnCurrentThread());
|
| +
|
| + bool was_above_limit = GetTotalBufferedBytes() > total_buffer_size_;
|
| +
|
| DCHECK_GE(output_size_used_, bytes_consumed);
|
| output_size_used_ -= bytes_consumed;
|
|
|
| // Callback if we were above the limit and we're now <= to it.
|
| - size_t total_known_size_used =
|
| - input_contents_size_ + output_size_used_;
|
| + bool no_longer_above_limit = GetTotalBufferedBytes() <= total_buffer_size_;
|
|
|
| - if (total_known_size_used <= total_buffer_size_ &&
|
| - (total_known_size_used + bytes_consumed > total_buffer_size_) &&
|
| + if (no_longer_above_limit && was_above_limit &&
|
| !space_available_callback_.is_null())
|
| space_available_callback_.Run();
|
| }
|
|
|