Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(186)

Side by Side Diff: net/url_request/url_fetcher_core.cc

Issue 1732493002: Prevent URLFetcher::AppendChunkedData from dereferencing NULL pointers. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Merge Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/url_request/url_fetcher_core.h" 5 #include "net/url_request/url_fetcher_core.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 198
199 upload_content_type_ = content_type; 199 upload_content_type_ = content_type;
200 upload_content_.clear(); 200 upload_content_.clear();
201 is_chunked_upload_ = true; 201 is_chunked_upload_ = true;
202 } 202 }
203 203
204 void URLFetcherCore::AppendChunkToUpload(const std::string& content, 204 void URLFetcherCore::AppendChunkToUpload(const std::string& content,
205 bool is_last_chunk) { 205 bool is_last_chunk) {
206 DCHECK(delegate_task_runner_.get()); 206 DCHECK(delegate_task_runner_.get());
207 DCHECK(network_task_runner_.get()); 207 DCHECK(network_task_runner_.get());
208 DCHECK(is_chunked_upload_);
208 network_task_runner_->PostTask( 209 network_task_runner_->PostTask(
209 FROM_HERE, 210 FROM_HERE,
210 base::Bind(&URLFetcherCore::CompleteAddingUploadDataChunk, this, content, 211 base::Bind(&URLFetcherCore::CompleteAddingUploadDataChunk, this, content,
211 is_last_chunk)); 212 is_last_chunk));
212 } 213 }
213 214
214 void URLFetcherCore::SetLoadFlags(int load_flags) { 215 void URLFetcherCore::SetLoadFlags(int load_flags) {
215 load_flags_ = load_flags; 216 load_flags_ = load_flags;
216 } 217 }
217 218
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after
509 510
510 URLFetcherCore::~URLFetcherCore() { 511 URLFetcherCore::~URLFetcherCore() {
511 // |request_| should be NULL. If not, it's unsafe to delete it here since we 512 // |request_| should be NULL. If not, it's unsafe to delete it here since we
512 // may not be on the IO thread. 513 // may not be on the IO thread.
513 DCHECK(!request_.get()); 514 DCHECK(!request_.get());
514 } 515 }
515 516
516 void URLFetcherCore::StartOnIOThread() { 517 void URLFetcherCore::StartOnIOThread() {
517 DCHECK(network_task_runner_->BelongsToCurrentThread()); 518 DCHECK(network_task_runner_->BelongsToCurrentThread());
518 519
520 // Create ChunkedUploadDataStream, if needed, so the consumer can start
521 // appending data. Have to do it here because StartURLRequest() may be called
522 // asynchonously.
523 if (is_chunked_upload_) {
eroman 2016/03/22 19:05:37 What is the gap between when this runs, and when S
mmenke 2016/03/22 20:01:51 There are two gaps: The ResponseWriter may take a
524 chunked_stream_.reset(new ChunkedUploadDataStream(0));
525 chunked_stream_writer_ = chunked_stream_->CreateWriter();
526 }
527
519 if (!response_writer_) 528 if (!response_writer_)
520 response_writer_.reset(new URLFetcherStringWriter); 529 response_writer_.reset(new URLFetcherStringWriter);
521 530
522 const int result = response_writer_->Initialize( 531 const int result = response_writer_->Initialize(
523 base::Bind(&URLFetcherCore::DidInitializeWriter, this)); 532 base::Bind(&URLFetcherCore::DidInitializeWriter, this));
524 if (result != ERR_IO_PENDING) 533 if (result != ERR_IO_PENDING)
525 DidInitializeWriter(result); 534 DidInitializeWriter(result);
526 } 535 }
527 536
528 void URLFetcherCore::StartURLRequest() { 537 void URLFetcherCore::StartURLRequest() {
(...skipping 14 matching lines...) Expand all
543 DCHECK(!request_.get()); 552 DCHECK(!request_.get());
544 553
545 g_registry.Get().AddURLFetcherCore(this); 554 g_registry.Get().AddURLFetcherCore(this);
546 current_response_bytes_ = 0; 555 current_response_bytes_ = 0;
547 request_context_getter_->AddObserver(this); 556 request_context_getter_->AddObserver(this);
548 request_ = request_context_getter_->GetURLRequestContext()->CreateRequest( 557 request_ = request_context_getter_->GetURLRequestContext()->CreateRequest(
549 original_url_, DEFAULT_PRIORITY, this); 558 original_url_, DEFAULT_PRIORITY, this);
550 request_->set_stack_trace(stack_trace_); 559 request_->set_stack_trace(stack_trace_);
551 int flags = request_->load_flags() | load_flags_; 560 int flags = request_->load_flags() | load_flags_;
552 561
553 if (is_chunked_upload_) 562 // TODO(mmenke): This should really be with the other code to set the upload
554 request_->EnableChunkedUpload(); 563 // body, below.
564 if (chunked_stream_)
565 request_->set_upload(std::move(chunked_stream_));
566
555 request_->SetLoadFlags(flags); 567 request_->SetLoadFlags(flags);
556 request_->SetReferrer(referrer_); 568 request_->SetReferrer(referrer_);
557 request_->set_referrer_policy(referrer_policy_); 569 request_->set_referrer_policy(referrer_policy_);
558 request_->set_first_party_for_cookies(initiator_.is_empty() ? original_url_ 570 request_->set_first_party_for_cookies(initiator_.is_empty() ? original_url_
559 : initiator_); 571 : initiator_);
560 request_->set_initiator(initiator_.is_empty() ? url::Origin(original_url_) 572 request_->set_initiator(initiator_.is_empty() ? url::Origin(original_url_)
561 : url::Origin(initiator_)); 573 : url::Origin(initiator_));
562 if (url_request_data_key_ && !url_request_create_data_callback_.is_null()) { 574 if (url_request_data_key_ && !url_request_create_data_callback_.is_null()) {
563 request_->SetUserData(url_request_data_key_, 575 request_->SetUserData(url_request_data_key_,
564 url_request_create_data_callback_.Run()); 576 url_request_create_data_callback_.Run());
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
828 destination_url_backoff = 840 destination_url_backoff =
829 url_throttler_entry_->GetExponentialBackoffReleaseTime(); 841 url_throttler_entry_->GetExponentialBackoffReleaseTime();
830 } 842 }
831 843
832 return original_url_backoff > destination_url_backoff ? 844 return original_url_backoff > destination_url_backoff ?
833 original_url_backoff : destination_url_backoff; 845 original_url_backoff : destination_url_backoff;
834 } 846 }
835 847
836 void URLFetcherCore::CompleteAddingUploadDataChunk( 848 void URLFetcherCore::CompleteAddingUploadDataChunk(
837 const std::string& content, bool is_last_chunk) { 849 const std::string& content, bool is_last_chunk) {
838 if (was_cancelled_) {
839 // Since CompleteAddingUploadDataChunk() is posted as a *delayed* task, it
840 // may run after the URLFetcher was already stopped.
841 return;
842 }
843 DCHECK(is_chunked_upload_); 850 DCHECK(is_chunked_upload_);
844 DCHECK(request_.get());
845 DCHECK(!content.empty()); 851 DCHECK(!content.empty());
846 request_->AppendChunkToUpload(content.data(), 852 chunked_stream_writer_->AppendData(
847 static_cast<int>(content.length()), 853 content.data(), static_cast<int>(content.length()), is_last_chunk);
848 is_last_chunk);
849 } 854 }
850 855
851 int URLFetcherCore::WriteBuffer(scoped_refptr<DrainableIOBuffer> data) { 856 int URLFetcherCore::WriteBuffer(scoped_refptr<DrainableIOBuffer> data) {
852 while (data->BytesRemaining() > 0) { 857 while (data->BytesRemaining() > 0) {
853 const int result = response_writer_->Write( 858 const int result = response_writer_->Write(
854 data.get(), 859 data.get(),
855 data->BytesRemaining(), 860 data->BytesRemaining(),
856 base::Bind(&URLFetcherCore::DidWriteBuffer, this, data)); 861 base::Bind(&URLFetcherCore::DidWriteBuffer, this, data));
857 if (result < 0) { 862 if (result < 0) {
858 if (result != ERR_IO_PENDING) 863 if (result != ERR_IO_PENDING)
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
953 } 958 }
954 959
955 void URLFetcherCore::AssertHasNoUploadData() const { 960 void URLFetcherCore::AssertHasNoUploadData() const {
956 DCHECK(!upload_content_set_); 961 DCHECK(!upload_content_set_);
957 DCHECK(upload_content_.empty()); 962 DCHECK(upload_content_.empty());
958 DCHECK(upload_file_path_.empty()); 963 DCHECK(upload_file_path_.empty());
959 DCHECK(upload_stream_factory_.is_null()); 964 DCHECK(upload_stream_factory_.is_null());
960 } 965 }
961 966
962 } // namespace net 967 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698