From f1eb3ae2ccdb4669dfd0f9b72a86a7561131827f Mon Sep 17 00:00:00 2001 From: chenyang Date: Wed, 31 Jul 2024 11:49:13 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8DCVE-2024-5840?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: chenyang --- .../browser/loader/file_url_loader_factory.cc | 20 +++++++++++++++---- .../file_url_loader_factory_unittest.cc | 17 ++++++++++++++++ 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/content/browser/loader/file_url_loader_factory.cc b/content/browser/loader/file_url_loader_factory.cc index c78443a291..5186ef2c2a 100644 --- a/content/browser/loader/file_url_loader_factory.cc +++ b/content/browser/loader/file_url_loader_factory.cc @@ -315,13 +315,14 @@ class FileURLDirectoryLoader // The producer above will have already copied any parts of |pending_data_| // that couldn't be written immediately, so we can wipe it out here to begin // accumulating more data. + total_bytes_written_ += pending_data_.size(); pending_data_.clear(); } void OnDataWritten(MojoResult result) { transfer_in_progress_ = false; - int completion_status; + int status; if (result == MOJO_RESULT_OK) { if (!pending_data_.empty()) { // Keep flushing the data buffer as long as it's non-empty and pipe @@ -337,16 +338,21 @@ class FileURLDirectoryLoader // At this point we know the listing is complete and all available data // has been transferred. We inherit the status of the listing operation. - completion_status = listing_result_; + status = listing_result_; } else { - completion_status = net::ERR_FAILED; + status = net::ERR_FAILED; } // All the data has been written now. Close the data pipe. The consumer will // be notified that there will be no more data to read from now. data_producer_.reset(); - client_->OnComplete(network::URLLoaderCompletionStatus(completion_status)); + network::URLLoaderCompletionStatus completion_status(status); + completion_status.encoded_data_length = total_bytes_written_; + completion_status.encoded_body_length = total_bytes_written_; + completion_status.decoded_body_length = total_bytes_written_; + + client_->OnComplete(completion_status); client_.reset(); MaybeDeleteSelf(); @@ -363,6 +369,11 @@ class FileURLDirectoryLoader std::unique_ptr data_producer_; std::string pending_data_; bool transfer_in_progress_ = false; + + // In case of successful loads, this holds the total number of bytes written + // to the response. It is used to set some of the URLLoaderCompletionStatus + // data passed back to the URLLoaderClients (eg SimpleURLLoader). + uint64_t total_bytes_written_ = 0; }; #if BUILDFLAG(IS_OHOS) @@ -813,6 +824,7 @@ class FileURLLoader : public network::mojom::URLLoader { redirect_data_->link_following_policy = link_following_policy; redirect_data_->request.url = redirect_info.new_url; redirect_data_->observer = std::move(observer); + redirect_data_->response_type = response_type; redirect_data_->extra_response_headers = std::move(extra_response_headers); diff --git a/content/browser/loader/file_url_loader_factory_unittest.cc b/content/browser/loader/file_url_loader_factory_unittest.cc index bb2debecaf..5c8bb55218 100644 --- a/content/browser/loader/file_url_loader_factory_unittest.cc +++ b/content/browser/loader/file_url_loader_factory_unittest.cc @@ -8,6 +8,7 @@ #include #include "base/files/file_util.h" +#include "base/files/scoped_temp_dir.h" #include "base/path_service.h" #include "base/test/bind.h" #include "base/test/task_environment.h" @@ -228,6 +229,22 @@ TEST_F(FileURLLoaderFactoryTest, Allowlist) { EXPECT_EQ(net::ERR_FAILED, CreateLoaderAndRun(std::move(request))); } +// Test that response type is set correctly for directory listings. Regression +// test for https://crbug.com/41492103. +TEST_F(FileURLLoaderFactoryTest, ResponseTypeForDirectoryListings) { + base::ScopedTempDir dir; + ASSERT_TRUE(dir.CreateUniqueTempDir()); + auto request = std::make_unique(); + request->url = + net::FilePathToFileURL(dir.GetPath().StripTrailingSeparators()); + request->mode = network::mojom::RequestMode::kNoCors; + ASSERT_EQ(net::OK, CreateLoaderAndRun(std::move(request))); + + ASSERT_NE(ResponseInfo(), nullptr); + EXPECT_EQ(network::mojom::FetchResponseType::kOpaque, + ResponseInfo()->response_type); +} + } // namespace } // namespace content -- Gitee