title_validator.cc 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. // Copyright 2021 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "components/continuous_search/common/title_validator.h"
  5. #include "base/functional/not_fn.h"
  6. #include "base/logging.h"
  7. #include "base/strings/string_util.h"
  8. namespace continuous_search {
  9. namespace {
  10. // Based on frame.mojom `kMaxTitleChars`.
  11. constexpr size_t kMaxLength = 4096;
  12. // A unicode control character is any character in the set:
  13. // {[U0000, U0020), U007F}
  14. // We explicitly permit U000B LINE TABULATION inkeeping with the implementation
  15. // in blink::Documents CanonicalizedTitle method.
  16. bool IsUnicodeWhitespaceOrControl(wchar_t c) {
  17. return (c < 0x0020 || c == 0x007F || base::IsUnicodeWhitespace(c)) &&
  18. c != 0x000B;
  19. }
  20. template <typename T, typename CharT = typename T::value_type>
  21. std::basic_string<CharT> ValidateTitleT(T input) {
  22. auto begin_it = std::find_if(input.begin(), input.end(),
  23. base::not_fn(IsUnicodeWhitespaceOrControl));
  24. auto end_it = std::find_if(input.rbegin(), input.rend(),
  25. base::not_fn(IsUnicodeWhitespaceOrControl));
  26. std::basic_string<CharT> output;
  27. if (input.empty() || begin_it == input.end() || end_it == input.rend()) {
  28. return output;
  29. }
  30. const size_t first = begin_it - input.begin();
  31. const size_t last = std::distance(input.begin(), end_it.base());
  32. DCHECK_GT(last, first); // Invariant based on the find_if algorithm.
  33. const size_t length = last - first;
  34. const size_t max_output_size = std::min(length, kMaxLength);
  35. output.resize(max_output_size);
  36. size_t output_pos = 0;
  37. bool in_whitespace = false;
  38. for (auto c : input.substr(first, length)) {
  39. if (IsUnicodeWhitespaceOrControl(c)) {
  40. if (!in_whitespace) {
  41. in_whitespace = true;
  42. output[output_pos++] = L' ';
  43. }
  44. } else {
  45. in_whitespace = false;
  46. output[output_pos++] = c;
  47. }
  48. if (output_pos == kMaxLength) {
  49. break;
  50. }
  51. }
  52. output.resize(output_pos);
  53. return output;
  54. }
  55. } // namespace
  56. std::string ValidateTitleAscii(base::StringPiece title) {
  57. return ValidateTitleT(title);
  58. }
  59. std::u16string ValidateTitle(base::StringPiece16 title) {
  60. return ValidateTitleT(title);
  61. }
  62. } // namespace continuous_search