blob: 177af6eac4a78c028c4aab5c4b2046283f466b5d [file] [log] [blame]
// Copyright 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/continuous_search/common/title_validator.h"
#include "base/functional/not_fn.h"
#include "base/logging.h"
#include "base/strings/string_util.h"
namespace continuous_search {
namespace {
// Based on frame.mojom `kMaxTitleChars`.
constexpr size_t kMaxLength = 4096;
// A unicode control character is any character in the set:
// {[U0000, U0020), U007F}
// We explicitly permit U000B LINE TABULATION inkeeping with the implementation
// in blink::Documents CanonicalizedTitle method.
bool IsUnicodeWhitespaceOrControl(wchar_t c) {
return (c < 0x0020 || c == 0x007F || base::IsUnicodeWhitespace(c)) &&
c != 0x000B;
}
template <typename CharT>
std::basic_string<CharT> ValidateTitleT(base::BasicStringPiece<CharT> input) {
auto begin_it = std::find_if(input.begin(), input.end(),
base::not_fn(IsUnicodeWhitespaceOrControl));
auto end_it = std::find_if(input.rbegin(), input.rend(),
base::not_fn(IsUnicodeWhitespaceOrControl));
std::basic_string<CharT> output;
if (input.empty() || begin_it == input.end() || end_it == input.rend()) {
return output;
}
const size_t first = begin_it - input.begin();
const size_t last = std::distance(input.begin(), end_it.base());
DCHECK_GT(last, first); // Invariant based on the find_if algorithm.
const size_t length = last - first;
const size_t max_output_size = std::min(length, kMaxLength);
output.resize(max_output_size);
size_t output_pos = 0;
bool in_whitespace = false;
for (auto c : input.substr(first, length)) {
if (IsUnicodeWhitespaceOrControl(c)) {
if (!in_whitespace) {
in_whitespace = true;
output[output_pos++] = L' ';
}
} else {
in_whitespace = false;
output[output_pos++] = c;
}
if (output_pos == kMaxLength) {
break;
}
}
output.resize(output_pos);
return output;
}
} // namespace
std::string ValidateTitleAscii(base::StringPiece title) {
return ValidateTitleT(title);
}
std::u16string ValidateTitle(base::StringPiece16 title) {
return ValidateTitleT(title);
}
} // namespace continuous_search