Skip to content

Commit

Permalink
[Brave News]: Fix crash with non-utf-8 RSS feeds. (#15714)
Browse files Browse the repository at this point in the history
  • Loading branch information
fallaciousreasoning committed Nov 1, 2022
1 parent b85e246 commit 7f3b3b0
Showing 1 changed file with 26 additions and 6 deletions.
32 changes: 26 additions & 6 deletions components/brave_today/browser/direct_feed_controller.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "base/callback.h"
#include "base/containers/flat_set.h"
#include "base/guid.h"
#include "base/i18n/icu_string_conversions.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/strings/string_util.h"
Expand Down Expand Up @@ -47,6 +48,14 @@
namespace brave_news {

namespace {
std::string GetResponseCharset(network::SimpleURLLoader* loader) {
auto* response_info = loader->ResponseInfo();
if (!response_info) {
return "utf-8";
}

return response_info->charset.empty() ? "utf-8" : response_info->charset;
}

mojom::ArticlePtr RustFeedItemToArticle(const FeedItem& rust_feed_item) {
// We don't include description since there does not exist a
Expand Down Expand Up @@ -77,13 +86,22 @@ mojom::ArticlePtr RustFeedItemToArticle(const FeedItem& rust_feed_item) {

using ParseFeedCallback = base::OnceCallback<void(absl::optional<FeedData>)>;
void ParseFeedDataOffMainThread(const GURL& feed_url,
const std::string& body_content,
const std::string& charset,
std::string body_content,
ParseFeedCallback callback) {
base::ThreadPool::PostTaskAndReplyWithResult(
FROM_HERE,
base::BindOnce(
[](const GURL& feed_url,
const std::string& body_content) -> absl::optional<FeedData> {
[](const GURL& feed_url, const std::string& charset,
std::string body_content) -> absl::optional<FeedData> {
// Ensure the body is encoded as UTF-8.
if (!base::ConvertToUtf8AndNormalize(body_content, charset,
&body_content)) {
LOG(ERROR) << "Failed to convert body content of " << feed_url
<< " to utf-8";
return absl::nullopt;
}

brave_news::FeedData data;
if (!parse_feed_string(::rust::String(body_content), data)) {
VLOG(1) << feed_url.spec() << " not a valid feed.";
Expand All @@ -93,7 +111,7 @@ void ParseFeedDataOffMainThread(const GURL& feed_url,
}
return data;
},
feed_url, body_content),
feed_url, charset, std::move(body_content)),
std::move(callback));
}

Expand Down Expand Up @@ -188,6 +206,7 @@ void DirectFeedController::FindFeeds(
auto* loader = iter->get();
auto response_code = -1;
std::string mime_type;
std::string charset = GetResponseCharset(loader);
GURL final_url(loader->GetFinalURL());
base::flat_map<std::string, std::string> headers;
if (loader->ResponseInfo()) {
Expand All @@ -211,7 +230,7 @@ void DirectFeedController::FindFeeds(

// Response is valid, but still might not be a feed
ParseFeedDataOffMainThread(
feed_url, body_content,
feed_url, charset, std::move(body_content),
base::BindOnce(
[](const GURL& feed_url, const GURL& final_url,
const std::string& mime_type,
Expand Down Expand Up @@ -422,6 +441,7 @@ void DirectFeedController::OnResponse(
// Parse response data
auto* loader = iter->get();
auto response_code = -1;
std::string charset = GetResponseCharset(loader);
base::flat_map<std::string, std::string> headers;
if (loader->ResponseInfo()) {
auto headers_list = loader->ResponseInfo()->headers;
Expand All @@ -443,7 +463,7 @@ void DirectFeedController::OnResponse(
}

// Response is valid, but still might not be a feed
ParseFeedDataOffMainThread(feed_url, std::move(body_content),
ParseFeedDataOffMainThread(feed_url, charset, std::move(body_content),
base::BindOnce(
[](DownloadFeedCallback callback,
std::unique_ptr<DirectFeedResponse> result,
Expand Down

0 comments on commit 7f3b3b0

Please sign in to comment.