<commit_before>#include "quiche/http2/adapter/header_validator.h"

#include <array>

#include "absl/strings/escaping.h"
#include "absl/strings/numbers.h"
#include "quiche/http2/http2_constants.h"
#include "quiche/common/platform/api/quiche_logging.h"

namespace http2 {
namespace adapter {

namespace {

const absl::string_view kHttp2HeaderNameAllowedChars =
    "!#$%&\'*+-.0123456789"
    "^_`abcdefghijklmnopqrstuvwxyz|~";

const absl::string_view kHttp2HeaderValueAllowedChars =
    "\t "
    "!\"#$%&'()*+,-./"
    "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`"
    "abcdefghijklmnopqrstuvwxyz{|}~";

const absl::string_view kHttp2StatusValueAllowedChars = "0123456789";

const absl::string_view kValidAuthorityChars =
    "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~%!$&'()["
    "]*+,;=:";

using CharMap = std::array<bool, 256>;

CharMap BuildValidCharMap(absl::string_view valid_chars) {
  CharMap map;
  map.fill(false);
  for (char c : valid_chars) {
    // Cast to uint8_t, guaranteed to have 8 bits. A char may have more, leading
    // to possible indices above 256.
    map[static_cast<uint8_t>(c)] = true;
  }
  return map;
}
CharMap AllowObsText(CharMap map) {
  // Characters above 0x80 are allowed in header field values as `obs-text` in
  // RFC 7230.
  for (char c = 0xff; c >= 0x80; --c) {
    map[c] = true;
  }
  return map;
}

bool AllCharsInMap(absl::string_view str, const CharMap& map) {
  for (char c : str) {
    if (!map[static_cast<uint8_t>(c)]) {
      return false;
    }
  }
  return true;
}

bool IsValidHeaderName(absl::string_view name) {
  static const CharMap valid_chars =
      BuildValidCharMap(kHttp2HeaderNameAllowedChars);
  return AllCharsInMap(name, valid_chars);
}

bool IsValidHeaderValue(absl::string_view value, ObsTextOption option) {<commit_msg>Uses uint8_t for an array index value.<commit_after>#include "quiche/http2/adapter/header_validator.h"

#include <array>

#include "absl/strings/escaping.h"
#include "absl/strings/numbers.h"
#include "quiche/http2/http2_constants.h"
#include "quiche/common/platform/api/quiche_logging.h"

namespace http2 {
namespace adapter {

namespace {

const absl::string_view kHttp2HeaderNameAllowedChars =
    "!#$%&\'*+-.0123456789"
    "^_`abcdefghijklmnopqrstuvwxyz|~";

const absl::string_view kHttp2HeaderValueAllowedChars =
    "\t "
    "!\"#$%&'()*+,-./"
    "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`"
    "abcdefghijklmnopqrstuvwxyz{|}~";

const absl::string_view kHttp2StatusValueAllowedChars = "0123456789";

const absl::string_view kValidAuthorityChars =
    "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~%!$&'()["
    "]*+,;=:";

using CharMap = std::array<bool, 256>;

CharMap BuildValidCharMap(absl::string_view valid_chars) {
  CharMap map;
  map.fill(false);
  for (char c : valid_chars) {
    // Cast to uint8_t, guaranteed to have 8 bits. A char may have more, leading
    // to possible indices above 256.
    map[static_cast<uint8_t>(c)] = true;
  }
  return map;
}
CharMap AllowObsText(CharMap map) {
  // Characters above 0x80 are allowed in header field values as `obs-text` in
  // RFC 7230.
  for (uint8_t c = 0xff; c >= 0x80; --c) {
    map[c] = true;
  }
  return map;
}

bool AllCharsInMap(absl::string_view str, const CharMap& map) {
  for (char c : str) {
    if (!map[static_cast<uint8_t>(c)]) {
      return false;
    }
  }
  return true;
}

bool IsValidHeaderName(absl::string_view name) {
  static const CharMap valid_chars =
      BuildValidCharMap(kHttp2HeaderNameAllowedChars);
  return AllCharsInMap(name, valid_chars);
}

bool IsValidHeaderValue(absl::string_view value, ObsTextOption option) {
{'fraction_non_alphanumeric': 0.13979370249728557, 'fraction_numerical': 0.038002171552660155, 'mean_word_length': 4.566465256797583, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4905893', 'n_tokens_mistral': 1528, 'n_tokens_neox': 1401, 'n_words': 272}