// Copyright 2022 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 "quiche/balsa/balsa_frame.h"

#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <limits>
#include <memory>
#include <string>
#include <utility>

#include "absl/strings/match.h"
#include "absl/strings/numbers.h"
#include "absl/strings/string_view.h"
#include "quiche/balsa/balsa_enums.h"
#include "quiche/balsa/balsa_headers.h"
#include "quiche/balsa/balsa_visitor_interface.h"
#include "quiche/balsa/header_properties.h"
#include "quiche/balsa/http_validation_policy.h"
#include "quiche/common/platform/api/quiche_flag_utils.h"
#include "quiche/common/platform/api/quiche_logging.h"

// When comparing characters (other than == and !=), cast to unsigned char
// to make sure values above 127 rank as expected, even on platforms where char
// is signed and thus such values are represented as negative numbers before the
// cast.
#define CHAR_LT(a, b) \
  (static_cast<unsigned char>(a) < static_cast<unsigned char>(b))
#define CHAR_LE(a, b) \
  (static_cast<unsigned char>(a) <= static_cast<unsigned char>(b))
#define CHAR_GT(a, b) \
  (static_cast<unsigned char>(a) > static_cast<unsigned char>(b))
#define CHAR_GE(a, b) \
  (static_cast<unsigned char>(a) >= static_cast<unsigned char>(b))
#define QUICHE_DCHECK_CHAR_GE(a, b) \
  QUICHE_DCHECK_GE(static_cast<unsigned char>(a), static_cast<unsigned char>(b))

namespace quiche {

namespace {

using FirstLineValidationOption =
    HttpValidationPolicy::FirstLineValidationOption;

constexpr size_t kContinueStatusCode = 100;
constexpr size_t kSwitchingProtocolsStatusCode = 101;

constexpr absl::string_view kChunked = "chunked";
constexpr absl::string_view kContentLength = "content-length";
constexpr absl::string_view kIdentity = "identity";
constexpr absl::string_view kTransferEncoding = "transfer-encoding";

bool IsInterimResponse(size_t response_code) {
  return response_code >= 100 && response_code < 200;
}

// Returns true if `c` is in the set of `obs-text` characters defined in RFC
// 9110 Section 5.5.
bool IsObsTextChar(char c) { return static_cast<uint8_t>(c) >= 0x80; }

}  // namespace

void BalsaFrame::Reset() {
  last_char_was_slash_r_ = false;
  saw_non_newline_char_ = false;
  start_was_space_ = true;
  chunk_length_character_extracted_ = false;
  // is_request_ = true;               // not reset between messages.
  allow_reading_until_close_for_request_ = false;
  // request_was_head_ = false;        // not reset between messages.
  // max_header_length_ = 16 * 1024;   // not reset between messages.
  // visitor_ = &do_nothing_visitor_;  // not reset between messages.
  chunk_length_remaining_ = 0;
  content_length_remaining_ = 0;
  last_slash_n_idx_ = 0;
  term_chars_ = 0;
  parse_state_ = BalsaFrameEnums::READING_HEADER_AND_FIRSTLINE;
  last_error_ = BalsaFrameEnums::BALSA_NO_ERROR;
  lines_.clear();
  if (continue_headers_ != nullptr) {
    continue_headers_->Clear();
  }
  if (headers_ != nullptr) {
    headers_->Clear();
  }
  trailer_lines_.clear();
  start_of_trailer_line_ = 0;
  trailer_length_ = 0;
  if (trailers_ != nullptr) {
    trailers_->Clear();
  }
  is_valid_target_uri_ = true;
}

namespace {

// Within the line bounded by [current, end), parses a single "island",
// comprising a (possibly empty) span of whitespace followed by a (possibly
// empty) span of non-whitespace.
//
// Returns a pointer to the first whitespace character beyond this island, or
// returns end if no additional whitespace characters are present after this
// island.  (I.e., returnvalue == end || *returnvalue > ' ')
//
// Upon return, the whitespace span are the characters
// whose indices fall in [*first_whitespace, *first_nonwhite), while the
// non-whitespace span are the characters whose indices fall in
// [*first_nonwhite, returnvalue - begin).
inline char* ParseOneIsland(char* current, char* begin, char* end,
                            size_t* first_whitespace, size_t* first_nonwhite) {
  *first_whitespace = current - begin;
  while (current < end && CHAR_LE(*current, ' ')) {
    ++current;
  }
  *first_nonwhite = current - begin;
  while (current < end && CHAR_GT(*current, ' ')) {
    ++current;
  }
  return current;
}

}  // namespace

// Summary:
//     Parses the first line of either a request or response.
//     Note that in the case of a detected warning, error_code will be set
//   but the function will not return false.
//     Exactly zero or one warning or error (but not both) may be detected
//   by this function.
//     Note that this function will not write the data of the first-line
//   into the header's buffer (that should already have been done elsewhere).
//
// Pre-conditions:
//     begin != end
//     *begin should be a character which is > ' '. This implies that there
//   is at least one non-whitespace characters between [begin, end).
//   headers is a valid pointer to a BalsaHeaders class.
//     error_code is a valid pointer to a BalsaFrameEnums::ErrorCode value.
//     Entire first line must exist between [begin, end)
//     Exactly zero or one newlines -may- exist between [begin, end)
//     [begin, end) should exist in the header's buffer.
//
// Side-effects:
//   headers will be modified
//   error_code may be modified if either a warning or error is detected
//
// Returns:
//   True if no error (as opposed to warning) is detected.
//   False if an error (as opposed to warning) is detected.

//
// If there is indeed non-whitespace in the line, then the following
// will take care of this for you:
//  while (*begin <= ' ') ++begin;
//  ProcessFirstLine(begin, end, is_request, &headers, &error_code);
//

bool ParseHTTPFirstLine(char* begin, char* end, bool is_request,
                        BalsaHeaders* headers,
                        BalsaFrameEnums::ErrorCode* error_code,
                        FirstLineValidationOption whitespace_option,
                        FirstLineValidationOption multiple_spaces_option) {
  while (begin < end && (end[-1] == '\n' || end[-1] == '\r')) {
    --end;
  }

  if (whitespace_option != FirstLineValidationOption::NONE) {
    constexpr absl::string_view kBadWhitespace = "\r\t";
    char* pos = std::find_first_of(begin, end, kBadWhitespace.begin(),
                                   kBadWhitespace.end());
    if (pos != end) {
      if (whitespace_option == FirstLineValidationOption::REJECT) {
        *error_code = static_cast<BalsaFrameEnums::ErrorCode>(
            BalsaFrameEnums::INVALID_WS_IN_STATUS_LINE +
            static_cast<int>(is_request));
        return false;
      }
      QUICHE_DCHECK(whitespace_option == FirstLineValidationOption::SANITIZE);
      std::replace_if(
          pos, end, [](char c) { return c == '\r' || c == '\t'; }, ' ');
    }
  }
  char* current = ParseOneIsland(begin, begin, end, &headers->whitespace_1_idx_,
                                 &headers->non_whitespace_1_idx_);
  current = ParseOneIsland(current, begin, end, &headers->whitespace_2_idx_,
                           &headers->non_whitespace_2_idx_);
  current = ParseOneIsland(current, begin, end, &headers->whitespace_3_idx_,
                           &headers->non_whitespace_3_idx_);

  // Clean up any trailing whitespace that comes after the third island
  const char* last = end;
  while (current <= last && CHAR_LE(*last, ' ')) {
    --last;
  }
  headers->whitespace_4_idx_ = last - begin + 1;

  // Either the passed-in line is empty, or it starts with a non-whitespace
  // character.
  QUICHE_DCHECK(begin == end || static_cast<unsigned char>(*begin) > ' ');

  QUICHE_DCHECK_EQ(0u, headers->whitespace_1_idx_);
  QUICHE_DCHECK_EQ(0u, headers->non_whitespace_1_idx_);

  // If the line isn't empty, it has at least one non-whitespace character (see
  // first QUICHE_DCHECK), which will have been identified as a non-empty
  // [non_whitespace_1_idx_, whitespace_2_idx_).
  QUICHE_DCHECK(begin == end ||
                headers->non_whitespace_1_idx_ < headers->whitespace_2_idx_);

  if (headers->non_whitespace_2_idx_ == headers->whitespace_3_idx_) {
    // This error may be triggered if the second token is empty, OR there's no
    // WS after the first token; we don't bother to distinguish exactly which.
    // (I'm not sure why we distinguish different kinds of parse error at all,
    // actually.)
    // FAILED_TO_FIND_WS_AFTER_REQUEST_METHOD   for request
    // FAILED_TO_FIND_WS_AFTER_RESPONSE_VERSION for response
    *error_code = static_cast<BalsaFrameEnums::ErrorCode>(
        BalsaFrameEnums::FAILED_TO_FIND_WS_AFTER_RESPONSE_VERSION +
        static_cast<int>(is_request));
    if (!is_request) {  // FAILED_TO_FIND_WS_AFTER_RESPONSE_VERSION
      return false;
    }
  }
  if (headers->whitespace_3_idx_ == headers->non_whitespace_3_idx_) {
    if (*error_code == BalsaFrameEnums::BALSA_NO_ERROR) {
      // FAILED_TO_FIND_WS_AFTER_REQUEST_METHOD   for request
      // FAILED_TO_FIND_WS_AFTER_RESPONSE_VERSION for response
      *error_code = static_cast<BalsaFrameEnums::ErrorCode>(
          BalsaFrameEnums::FAILED_TO_FIND_WS_AFTER_RESPONSE_STATUSCODE +
          static_cast<int>(is_request));
    }
  }

  if (!is_request) {
    headers->parsed_response_code_ = 0;
    // If the response code is non-empty:
    if (headers->non_whitespace_2_idx_ < headers->whitespace_3_idx_) {
      if (!absl::SimpleAtoi(
              absl::string_view(begin + headers->non_whitespace_2_idx_,
                                headers->non_whitespace_3_idx_ -
                                    headers->non_whitespace_2_idx_),
              &headers->parsed_response_code_)) {
        *error_code = BalsaFrameEnums::FAILED_CONVERTING_STATUS_CODE_TO_INT;
        return false;
      }
    }
  }

  if (multiple_spaces_option != FirstLineValidationOption::NONE &&
      absl::StrContains(headers->first_line(), "  ")) {
    if (multiple_spaces_option == FirstLineValidationOption::REJECT) {
      *error_code = is_request
                        ? BalsaFrameEnums::MULTIPLE_SPACES_IN_REQUEST_LINE
                        : BalsaFrameEnums::MULTIPLE_SPACES_IN_STATUS_LINE;
      return false;
    }
    const absl::string_view part1(
        begin + headers->non_whitespace_1_idx_,
        headers->whitespace_2_idx_ - headers->non_whitespace_1_idx_);
    const absl::string_view part2(
        begin + headers->non_whitespace_2_idx_,
        headers->whitespace_3_idx_ - headers->non_whitespace_2_idx_);
    const absl::string_view part3(
        begin + headers->non_whitespace_3_idx_,
        headers->whitespace_4_idx_ - headers->non_whitespace_3_idx_);

    headers->SetRequestFirstlineFromStringPieces(part1, part2, part3);
  }

  return true;
}

namespace {
bool IsValidTargetUri(absl::string_view method, absl::string_view target_uri) {
  if (target_uri.empty()) {
    QUICHE_CODE_COUNT(invalid_target_uri_empty);
    return false;
  }
  // HTTP/1.1 allows for a path of "*" for OPTIONS requests, based on RFC
  // 9112, https://www.rfc-editor.org/rfc/rfc9112.html#section-3.2.4:
  //
  // The asterisk-form of request-target is only used for a server-wide OPTIONS
  // request
  // ...
  // asterisk-form  = "*"
  if (target_uri == "*") {
    if (method == "OPTIONS") {
      return true;
    }
    QUICHE_CODE_COUNT(invalid_target_uri_asterisk_not_options);
    return false;
  }
  if (method == "CONNECT") {
    // The :authority must be authority-form for CONNECT method requests. From
    // RFC 9112: https://www.rfc-editor.org/rfc/rfc9112.html#section-3.2.3:
    //
    // The "authority-form" of request-target is only used for CONNECT requests
    // (Section 9.3.6 of [HTTP]). It consists of only the uri-host and port
    // number of the tunnel destination, separated by a colon (":").
    //
    //    authority-form = uri-host ":" port
    //
    // When making a CONNECT request to establish a tunnel through one or more
    // proxies, a client MUST send only the host and port of the tunnel
    // destination as the request-target. The client obtains the host and port
    // from the target URI's authority component, except that it sends the
    // scheme's default port if the target URI elides the port. For example, a
    // CONNECT request to "http://www.example.com" looks like the following:
    //
    //    CONNECT www.example.com:80 HTTP/1.1
    //    Host: www.example.com
    //
    // Also from RFC 9110, the CONNECT request-target must have a valid port
    // number, https://www.rfc-editor.org/rfc/rfc9110.html#section-9.3.6:
    //
    // A server MUST reject a CONNECT request that targets an empty or invalid
    // port number, typically by responding with a 400 (Bad Request) status code
    size_t index = target_uri.find_last_of(':');
    if (index == absl::string_view::npos || index == 0) {
      QUICHE_CODE_COUNT(invalid_target_uri_connect_missing_port);
      return false;
    }
    // This is an IPv6 address and must have the closing "]" bracket just prior
    // to the port delimiter.
    if (target_uri[0] == '[' && target_uri[index - 1] != ']') {
      QUICHE_CODE_COUNT(invalid_target_uri_connect_bad_v6_literal);
      return false;
    }
    int port;
    if (!absl::SimpleAtoi(target_uri.substr(index + 1), &port) || port < 0 ||
        port > 65535) {
      QUICHE_CODE_COUNT(invalid_target_uri_connect_bad_port);
      return false;
    }
    return true;
  }

  // From RFC 9112: https://www.rfc-editor.org/rfc/rfc9112.html#name-origin-form
  //
  // When making a request directly to an origin server, other than a CONNECT
  // or server-wide OPTIONS request (as detailed below), a client MUST send
  // only the absolute path and query components of the target URI as the
  // request-target. If the target URI's path component is empty, the client
  // MUST send "/" as the path within the origin-form of request-target.
  //
  // https://www.rfc-editor.org/rfc/rfc9112.html#name-absolute-form
  // When making a request to a proxy, other than a CONNECT or server-wide
  // OPTIONS request (as detailed below), a client MUST send the target URI
  // in "absolute-form" as the request-target.
  //
  // https://www.rfc-editor.org/rfc/rfc3986.html#section-4.2
  // https://www.rfc-editor.org/rfc/rfc3986.html#section-4.3
  if (target_uri[0] == '/' || absl::StrContains(target_uri, "://")) {
    return true;
  }
  QUICHE_CODE_COUNT(invalid_target_uri_bad_path);
  return false;
}
}  // namespace

// begin - beginning of the firstline
// end - end of the firstline
//
// A precondition for this function is that there is non-whitespace between
// [begin, end). If this precondition is not met, the function will not perform
// as expected (and bad things may happen, and it will eat your first, second,
// and third unborn children!).
//
// Another precondition for this function is that [begin, end) includes
// at most one newline, which must be at the end of the line.
void BalsaFrame::ProcessFirstLine(char* begin, char* end) {
  BalsaFrameEnums::ErrorCode previous_error = last_error_;
  if (!ParseHTTPFirstLine(
          begin, end, is_request_, headers_, &last_error_,
          http_validation_policy().sanitize_cr_tab_in_first_line,
          http_validation_policy().sanitize_firstline_spaces)) {
    parse_state_ = BalsaFrameEnums::ERROR;
    HandleError(last_error_);
    return;
  }
  if (previous_error != last_error_) {
    HandleWarning(last_error_);
  }

  const absl::string_view line_input(
      begin + headers_->non_whitespace_1_idx_,
      headers_->whitespace_4_idx_ - headers_->non_whitespace_1_idx_);
  const absl::string_view part1(
      begin + headers_->non_whitespace_1_idx_,
      headers_->whitespace_2_idx_ - headers_->non_whitespace_1_idx_);
  const absl::string_view part2(
      begin + headers_->non_whitespace_2_idx_,
      headers_->whitespace_3_idx_ - headers_->non_whitespace_2_idx_);
  const absl::string_view part3(
      begin + headers_->non_whitespace_3_idx_,
      headers_->whitespace_4_idx_ - headers_->non_whitespace_3_idx_);

  if (is_request_) {
    is_valid_target_uri_ = IsValidTargetUri(part1, part2);
    if (http_validation_policy().disallow_invalid_target_uris &&
        !is_valid_target_uri_) {
      parse_state_ = BalsaFrameEnums::ERROR;
      last_error_ = BalsaFrameEnums::INVALID_TARGET_URI;
      HandleError(last_error_);
      return;
    }
    visitor_->OnRequestFirstLineInput(line_input, part1, part2, part3);
    if (part3.empty()) {
      parse_state_ = BalsaFrameEnums::MESSAGE_FULLY_READ;
    }
    return;
  }

  visitor_->OnResponseFirstLineInput(line_input, part1, part2, part3);
}

// 'stream_begin' points to the first character of the headers buffer.
// 'line_begin' points to the first character of the line.
// 'current' points to a char which is ':'.
// 'line_end' points to the position of '\n' + 1.
// 'line_begin' points to the position of first character of line.
void BalsaFrame::CleanUpKeyValueWhitespace(
    const char* stream_begin, const char* line_begin, const char* current,
    const char* line_end, HeaderLineDescription* current_header_line) {
  const char* colon_loc = current;
  QUICHE_DCHECK_LT(colon_loc, line_end);
  QUICHE_DCHECK_EQ(':', *colon_loc);
  QUICHE_DCHECK_EQ(':', *current);
  QUICHE_DCHECK_CHAR_GE(' ', *line_end)
      << "\"" << std::string(line_begin, line_end) << "\"";

  --current;
  while (current > line_begin && CHAR_LE(*current, ' ')) {
    --current;
  }
  current += static_cast<int>(current != colon_loc);
  current_header_line->key_end_idx = current - stream_begin;

  current = colon_loc;
  QUICHE_DCHECK_EQ(':', *current);
  ++current;
  while (current < line_end && CHAR_LE(*current, ' ')) {
    ++current;
  }
  current_header_line->value_begin_idx = current - stream_begin;

  QUICHE_DCHECK_GE(current_header_line->key_end_idx,
                   current_header_line->first_char_idx);
  QUICHE_DCHECK_GE(current_header_line->value_begin_idx,
                   current_header_line->key_end_idx);
  QUICHE_DCHECK_GE(current_header_line->last_char_idx,
                   current_header_line->value_begin_idx);
}

bool BalsaFrame::FindColonsAndParseIntoKeyValue(const Lines& lines,
                                                bool is_trailer,
                                                BalsaHeaders* headers) {
  QUICHE_DCHECK(!lines.empty());
  const char* stream_begin = headers->OriginalHeaderStreamBegin();
  // The last line is always just a newline (and is uninteresting).
  const Lines::size_type lines_size_m1 = lines.size() - 1;
  // For a trailer, there is no first line, so lines[0] is the first header.
  // For real headers, the first line takes lines[0], so real header starts
  // at index 1.
  int first_header_idx = (is_trailer ? 0 : 1);
  const char* current = stream_begin + lines[first_header_idx].first;
  // This code is a bit more subtle than it may appear at first glance.
  // This code looks for a colon in the current line... but it also looks
  // beyond the current line. If there is no colon in the current line, then
  // for each subsequent line (until the colon which -has- been found is
  // associated with a line), no searching for a colon will be performed. In
  // this way, we minimize the amount of bytes we have scanned for a colon.
  for (Lines::size_type i = first_header_idx; i < lines_size_m1;) {
    const char* line_begin = stream_begin + lines[i].first;

    // Here we handle possible continuations.  Note that we do not replace
    // the '\n' in the line before a continuation (at least, as of now),
    // which implies that any code which looks for a value must deal with
    // "\r\n", etc -within- the line (and not just at the end of it).
    for (++i; i < lines_size_m1; ++i) {
      const char c = *(stream_begin + lines[i].first);
      if (CHAR_GT(c, ' ')) {
        // Not a continuation, so stop.  Note that if the 'original' i = 1,
        // and the next line is not a continuation, we'll end up with i = 2
        // when we break. This handles the incrementing of i for the outer
        // loop.
        break;
      }

      // Space and tab are valid starts to continuation lines.
      // https://tools.ietf.org/html/rfc7230#section-3.2.4 says that a proxy
      // can choose to reject or normalize continuation lines.
      if ((c != ' ' && c != '\t') ||
          http_validation_policy().disallow_header_continuation_lines) {
        HandleError(is_trailer ? BalsaFrameEnums::INVALID_TRAILER_FORMAT
                               : BalsaFrameEnums::INVALID_HEADER_FORMAT);
        return false;
      }
      // Getting here means we find obs-fold character (for header line
      // continuation) and continuation is allowed.
      HandleWarning(is_trailer ? BalsaFrameEnums::OBS_FOLD_IN_TRAILERS
                               : BalsaFrameEnums::OBS_FOLD_IN_HEADERS);

      // If disallow_header_continuation_lines() is false, we neither reject nor
      // normalize continuation lines, in violation of RFC7230.
    }
    const char* line_end = stream_begin + lines[i - 1].second;
    QUICHE_DCHECK_LT(line_begin - stream_begin, line_end - stream_begin);

    // We cleanup the whitespace at the end of the line before doing anything
    // else of interest as it allows us to do nothing when irregularly formatted
    // headers are parsed (e.g. those with only keys, only values, or no colon).
    //
    // We're guaranteed to have *line_end > ' ' while line_end >= line_begin.
    --line_end;
    QUICHE_DCHECK_EQ('\n', *line_end)
        << "\"" << std::string(line_begin, line_end) << "\"";
    while (CHAR_LE(*line_end, ' ') && line_end > line_begin) {
      --line_end;
    }
    ++line_end;
    QUICHE_DCHECK_CHAR_GE(' ', *line_end);
    QUICHE_DCHECK_LT(line_begin, line_end);

    // We use '0' for the block idx, because we're always writing to the first
    // block from the framer (we do this because the framer requires that the
    // entire header sequence be in a contiguous buffer).
    headers->header_lines_.push_back(HeaderLineDescription(
        line_begin - stream_begin, line_end - stream_begin,
        line_end - stream_begin, line_end - stream_begin, 0));
    if (current >= line_end) {
      if (http_validation_policy().require_header_colon) {
        HandleError(is_trailer ? BalsaFrameEnums::TRAILER_MISSING_COLON
                               : BalsaFrameEnums::HEADER_MISSING_COLON);
        return false;
      }
      HandleWarning(is_trailer ? BalsaFrameEnums::TRAILER_MISSING_COLON
                               : BalsaFrameEnums::HEADER_MISSING_COLON);
      // Then the next colon will not be found within this header line-- time
      // to try again with another header-line.
      continue;
    }
    if (current < line_begin) {
      // When this condition is true, the last detected colon was part of a
      // previous line.  We reset to the beginning of the line as we don't care
      // about the presence of any colon before the beginning of the current
      // line.
      current = line_begin;
    }
    for (; current < line_end; ++current) {
      const char c = *current;
      if (c == ':') {
        break;
      }

      // Generally invalid characters were found earlier.
      if (http_validation_policy().disallow_double_quote_in_header_name) {
        if (header_properties::IsInvalidHeaderKeyChar(c)) {
          HandleError(is_trailer
                          ? BalsaFrameEnums::INVALID_TRAILER_NAME_CHARACTER
                          : BalsaFrameEnums::INVALID_HEADER_NAME_CHARACTER);
          return false;
        }
      } else if (header_properties::IsInvalidHeaderKeyCharAllowDoubleQuote(c)) {
        HandleError(is_trailer
                        ? BalsaFrameEnums::INVALID_TRAILER_NAME_CHARACTER
                        : BalsaFrameEnums::INVALID_HEADER_NAME_CHARACTER);
        return false;
      }

      if (http_validation_policy().disallow_obs_text_in_field_names &&
          IsObsTextChar(c)) {
        HandleError(is_trailer
                        ? BalsaFrameEnums::INVALID_TRAILER_NAME_CHARACTER
                        : BalsaFrameEnums::INVALID_HEADER_NAME_CHARACTER);
        return false;
      }
    }

    if (current == line_end) {
      // There was no colon in the line. The arguments we passed into the
      // construction for the HeaderLineDescription object should be OK-- it
      // assumes that the entire content is 'key' by default (which is true, as
      // there was no colon, there can be no value). Note that this is a
      // construct which is technically not allowed by the spec.

      // In strict mode, we do treat this invalid value-less key as an error.
      if (http_validation_policy().require_header_colon) {
        HandleError(is_trailer ? BalsaFrameEnums::TRAILER_MISSING_COLON
                               : BalsaFrameEnums::HEADER_MISSING_COLON);
        return false;
      }
      HandleWarning(is_trailer ? BalsaFrameEnums::TRAILER_MISSING_COLON
                               : BalsaFrameEnums::HEADER_MISSING_COLON);
      continue;
    }

    QUICHE_DCHECK_EQ(*current, ':');
    QUICHE_DCHECK_LE(current - stream_begin, line_end - stream_begin);
    QUICHE_DCHECK_LE(stream_begin - stream_begin, current - stream_begin);

    HeaderLineDescription& current_header_line = headers->header_lines_.back();
    current_header_line.key_end_idx = current - stream_begin;
    current_header_line.value_begin_idx = current_header_line.key_end_idx;
    if (current < line_end) {
      ++current_header_line.key_end_idx;

      CleanUpKeyValueWhitespace(stream_begin, line_begin, current, line_end,
                                &current_header_line);
    }
  }

  return true;
}

void BalsaFrame::HandleWarning(BalsaFrameEnums::ErrorCode error_code) {
  last_error_ = error_code;
  visitor_->HandleWarning(last_error_);
}

void BalsaFrame::HandleError(BalsaFrameEnums::ErrorCode error_code) {
  last_error_ = error_code;
  parse_state_ = BalsaFrameEnums::ERROR;
  visitor_->HandleError(last_error_);
}

BalsaHeadersEnums::ContentLengthStatus BalsaFrame::ProcessContentLengthLine(
    HeaderLines::size_type line_idx, size_t* length) {
  const HeaderLineDescription& header_line = headers_->header_lines_[line_idx];
  const char* stream_begin = headers_->OriginalHeaderStreamBegin();
  const char* line_end = stream_begin + header_line.last_char_idx;
  const char* value_begin = (stream_begin + header_line.value_begin_idx);

  if (value_begin >= line_end) {
    // There is no non-whitespace value data.
    QUICHE_DVLOG(1) << "invalid content-length -- no non-whitespace value data";
    return BalsaHeadersEnums::INVALID_CONTENT_LENGTH;
  }

  *length = 0;
  while (value_begin < line_end) {
    if (*value_begin < '0' || *value_begin > '9') {
      // bad! content-length found, and couldn't parse all of it!
      QUICHE_DVLOG(1)
          << "invalid content-length - non numeric character detected";
      return BalsaHeadersEnums::INVALID_CONTENT_LENGTH;
    }
    const size_t kMaxDiv10 = std::numeric_limits<size_t>::max() / 10;
    size_t length_x_10 = *length * 10;
    const size_t c = *value_begin - '0';
    if (*length > kMaxDiv10 ||
        (std::numeric_limits<size_t>::max() - length_x_10) < c) {
      QUICHE_DVLOG(1) << "content-length overflow";
      return BalsaHeadersEnums::CONTENT_LENGTH_OVERFLOW;
    }
    *length = length_x_10 + c;
    ++value_begin;
  }
  QUICHE_DVLOG(1) << "content_length parsed: " << *length;
  return BalsaHeadersEnums::VALID_CONTENT_LENGTH;
}

void BalsaFrame::ProcessTransferEncodingLine(HeaderLines::size_type line_idx) {
  const HeaderLineDescription& header_line = headers_->header_lines_[line_idx];
  const char* stream_begin = headers_->OriginalHeaderStreamBegin();
  const absl::string_view transfer_encoding(
      stream_begin + header_line.value_begin_idx,
      header_line.last_char_idx - header_line.value_begin_idx);

  if (absl::EqualsIgnoreCase(transfer_encoding, kChunked)) {
    headers_->transfer_encoding_is_chunked_ = true;
    return;
  }

  if (absl::EqualsIgnoreCase(transfer_encoding, kIdentity)) {
    headers_->transfer_encoding_is_chunked_ = false;
    return;
  }

  if (http_validation_policy().validate_transfer_encoding) {
    HandleError(BalsaFrameEnums::UNKNOWN_TRANSFER_ENCODING);
  }
}

bool BalsaFrame::CheckHeaderLinesForInvalidChars(const Lines& lines,
                                                 const BalsaHeaders* headers) {
  // Read from the beginning of the first line to the end of the last line.
  // Note we need to add the first line's offset as in the case of a trailer
  // it's non-zero.
  const char* stream_begin =
      headers->OriginalHeaderStreamBegin() + lines.front().first;
  const char* stream_end =
      headers->OriginalHeaderStreamBegin() + lines.back().second;

  for (const char* c = stream_begin; c < stream_end; c++) {
    if (header_properties::IsInvalidHeaderChar(*c)) {
      return true;
    }
    if (*c == '\r' &&
        http_validation_policy().disallow_lone_cr_in_request_headers &&
        c + 1 < stream_end && *(c + 1) != '\n') {
      return true;
    }
  }

  return false;
}

void BalsaFrame::ProcessHeaderLines(const Lines& lines, bool is_trailer,
                                    BalsaHeaders* headers) {
  QUICHE_DCHECK(!lines.empty());
  QUICHE_DVLOG(1) << "******@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@**********\n";

  if (invalid_chars_error_enabled() &&
      CheckHeaderLinesForInvalidChars(lines, headers)) {
    HandleError(BalsaFrameEnums::INVALID_HEADER_CHARACTER);
    return;
  }

  // There is no need to attempt to process headers (resp. trailers)
  // if no header (resp. trailer) lines exist.
  //
  // The last line of the message, which is an empty line, is never a header
  // (resp. trailer) line.  Furthermore, the first line of the message is not
  // a header line.  Therefore there are at least two (resp. one) lines in the
  // message which are not header (resp. trailer) lines.
  //
  // Thus, we test to see if we have more than two (resp. one) lines total
  // before attempting to parse any header (resp. trailer) lines.
  if (lines.size() <= (is_trailer ? 1 : 2)) {
    return;
  }

  HeaderLines::size_type content_length_idx = 0;
  HeaderLines::size_type transfer_encoding_idx = 0;
  const char* stream_begin = headers->OriginalHeaderStreamBegin();
  // Parse the rest of the header or trailer data into key-value pairs.
  if (!FindColonsAndParseIntoKeyValue(lines, is_trailer, headers)) {
    return;
  }
  // At this point, we've parsed all of the headers/trailers.  Time to look
  // for those headers which we require for framing or for format errors.
  const HeaderLines::size_type lines_size = headers->header_lines_.size();
  for (HeaderLines::size_type i = 0; i < lines_size; ++i) {
    const HeaderLineDescription& line = headers->header_lines_[i];
    const absl::string_view key(stream_begin + line.first_char_idx,
                                line.key_end_idx - line.first_char_idx);
    QUICHE_DVLOG(2) << "[" << i << "]: " << key << " key_len: " << key.length();

    // If a header begins with either lowercase or uppercase 'c' or 't', then
    // the header may be one of content-length, connection, content-encoding
    // or transfer-encoding. These headers are special, as they change the way
    // that the message is framed, and so the framer is required to search
    // for them.  However, first check for a formatting error, and skip
    // special header treatment on trailer lines (when is_trailer is true).
    if (key.empty() || key[0] == ' ') {
      parse_state_ = BalsaFrameEnums::ERROR;
      HandleError(is_trailer ? BalsaFrameEnums::INVALID_TRAILER_FORMAT
                             : BalsaFrameEnums::INVALID_HEADER_FORMAT);
      return;
    }
    if (is_trailer) {
      continue;
    }
    if (absl::EqualsIgnoreCase(key, kContentLength)) {
      size_t length = 0;
      BalsaHeadersEnums::ContentLengthStatus content_length_status =
          ProcessContentLengthLine(i, &length);
      if (content_length_idx == 0) {
        content_length_idx = i + 1;
        headers->content_length_status_ = content_length_status;
        headers->content_length_ = length;
        content_length_remaining_ = length;
        continue;
      }
      if ((headers->content_length_status_ != content_length_status) ||
          ((headers->content_length_status_ ==
            BalsaHeadersEnums::VALID_CONTENT_LENGTH) &&
           (http_validation_policy().disallow_multiple_content_length ||
            length != headers->content_length_))) {
        HandleError(BalsaFrameEnums::MULTIPLE_CONTENT_LENGTH_KEYS);
        return;
      }
      continue;
    }
    if (absl::EqualsIgnoreCase(key, kTransferEncoding)) {
      if (http_validation_policy().validate_transfer_encoding &&
          transfer_encoding_idx != 0) {
        HandleError(BalsaFrameEnums::MULTIPLE_TRANSFER_ENCODING_KEYS);
        return;
      }
      transfer_encoding_idx = i + 1;
    }
  }

  if (!is_trailer) {
    if (http_validation_policy().validate_transfer_encoding &&
        http_validation_policy()
            .disallow_transfer_encoding_with_content_length &&
        content_length_idx != 0 && transfer_encoding_idx != 0) {
      HandleError(BalsaFrameEnums::BOTH_TRANSFER_ENCODING_AND_CONTENT_LENGTH);
      return;
    }
    if (headers->transfer_encoding_is_chunked_) {
      headers->content_length_ = 0;
      headers->content_length_status_ = BalsaHeadersEnums::NO_CONTENT_LENGTH;
      content_length_remaining_ = 0;
    }
    if (transfer_encoding_idx != 0) {
      ProcessTransferEncodingLine(transfer_encoding_idx - 1);
    }
  }
}

void BalsaFrame::AssignParseStateAfterHeadersHaveBeenParsed() {
  // For responses, can't have a body if the request was a HEAD, or if it is
  // one of these response-codes.  rfc2616 section 4.3
  parse_state_ = BalsaFrameEnums::MESSAGE_FULLY_READ;
  int response_code = headers_->parsed_response_code_;
  if (!is_request_ && (request_was_head_ ||
                       !BalsaHeaders::ResponseCanHaveBody(response_code))) {
    // There is no body.
    return;
  }

  if (headers_->transfer_encoding_is_chunked_) {
    // Note that
    // if ( Transfer-Encoding: chunked &&  Content-length: )
    // then Transfer-Encoding: chunked trumps.
    // This is as specified in the spec.
    // rfc2616 section 4.4.3
    parse_state_ = BalsaFrameEnums::READING_CHUNK_LENGTH;
    return;
  }

  // Errors parsing content-length definitely can cause
  // protocol errors/warnings
  switch (headers_->content_length_status_) {
    // If we have a content-length, and it is parsed
    // properly, there are two options.
    // 1) zero content, in which case the message is done, and
    // 2) nonzero content, in which case we have to
    //    consume the body.
    case BalsaHeadersEnums::VALID_CONTENT_LENGTH:
      if (headers_->content_length_ == 0) {
        parse_state_ = BalsaFrameEnums::MESSAGE_FULLY_READ;
      } else {
        parse_state_ = BalsaFrameEnums::READING_CONTENT;
      }
      break;
    case BalsaHeadersEnums::CONTENT_LENGTH_OVERFLOW:
    case BalsaHeadersEnums::INVALID_CONTENT_LENGTH:
      // If there were characters left-over after parsing the
      // content length, we should flag an error and stop.
      HandleError(BalsaFrameEnums::UNPARSABLE_CONTENT_LENGTH);
      break;
      // We can have: no transfer-encoding, no content length, and no
      // connection: close...
      // Unfortunately, this case doesn't seem to be covered in the spec.
      // We'll assume that the safest thing to do here is what the google
      // binaries before 2008 already do, which is to assume that
      // everything until the connection is closed is body.
    case BalsaHeadersEnums::NO_CONTENT_LENGTH:
      if (is_request_) {
        const absl::string_view method = headers_->request_method();
        // POSTs and PUTs should have a detectable body length.  If they
        // do not we consider it an error.
        if ((method != "POST" && method != "PUT") ||
            !http_validation_policy().require_content_length_if_body_required) {
          parse_state_ = BalsaFrameEnums::MESSAGE_FULLY_READ;
          break;
        } else if (!allow_reading_until_close_for_request_) {
          HandleError(BalsaFrameEnums::REQUIRED_BODY_BUT_NO_CONTENT_LENGTH);
          break;
        }
      }
      parse_state_ = BalsaFrameEnums::READING_UNTIL_CLOSE;
      HandleWarning(BalsaFrameEnums::MAYBE_BODY_BUT_NO_CONTENT_LENGTH);
      break;
      // The COV_NF_... statements here provide hints to the apparatus
      // which computes coverage reports/ratios that this code is never
      // intended to be executed, and should technically be impossible.
      // COV_NF_START
    default:
      QUICHE_LOG(FATAL) << "Saw a content_length_status: "
                        << headers_->content_length_status_
                        << " which is unknown.";
      // COV_NF_END
  }
}

size_t BalsaFrame::ProcessHeaders(const char* message_start,
                                  size_t message_length) {
  const char* const original_message_start = message_start;
  const char* const message_end = message_start + message_length;
  const char* message_current = message_start;
  const char* checkpoint = message_start;

  if (message_length == 0) {
    return message_current - original_message_start;
  }

  while (message_current < message_end) {
    size_t base_idx = headers_->GetReadableBytesFromHeaderStream();

    // Yes, we could use strchr (assuming null termination), or
    // memchr, but as it turns out that is slower than this tight loop
    // for the input that we see.
    if (!saw_non_newline_char_) {
      do {
        const char c = *message_current;
        if (c != '\r' && c != '\n') {
          if (CHAR_LE(c, ' ')) {
            HandleError(BalsaFrameEnums::NO_REQUEST_LINE_IN_REQUEST);
            return message_current - original_message_start;
          }
          break;
        }
        ++message_current;
        if (message_current == message_end) {
          return message_current - original_message_start;
        }
      } while (true);
      saw_non_newline_char_ = true;
      message_start = message_current;
      checkpoint = message_current;
    }
    while (message_current < message_end) {
      if (*message_current != '\n') {
        ++message_current;
        continue;
      }
      const size_t relative_idx = message_current - message_start;
      const size_t message_current_idx = 1 + base_idx + relative_idx;
      lines_.push_back(std::make_pair(last_slash_n_idx_, message_current_idx));
      if (lines_.size() == 1) {
        headers_->WriteFromFramer(checkpoint, 1 + message_current - checkpoint);
        checkpoint = message_current + 1;
        char* begin = headers_->OriginalHeaderStreamBegin();

        QUICHE_DVLOG(1) << "First line "
                        << std::string(begin, lines_[0].second);
        QUICHE_DVLOG(1) << "is_request_: " << is_request_;
        ProcessFirstLine(begin, begin + lines_[0].second);
        if (parse_state_ == BalsaFrameEnums::MESSAGE_FULLY_READ) {
          break;
        }

        if (parse_state_ == BalsaFrameEnums::ERROR) {
          return message_current - original_message_start;
        }
      }
      const size_t chars_since_last_slash_n =
          (message_current_idx - last_slash_n_idx_);
      last_slash_n_idx_ = message_current_idx;
      if (chars_since_last_slash_n > 2) {
        // false positive.
        ++message_current;
        continue;
      }
      if ((chars_since_last_slash_n == 1) ||
          (((message_current > message_start) &&
            (*(message_current - 1) == '\r')) ||
           (last_char_was_slash_r_))) {
        break;
      }
      ++message_current;
    }

    if (message_current == message_end) {
      continue;
    }

    ++message_current;
    QUICHE_DCHECK(message_current >= message_start);
    if (message_current > message_start) {
      headers_->WriteFromFramer(checkpoint, message_current - checkpoint);
    }

    // Check if we have exceeded maximum headers length
    // Although we check for this limit before and after we call this function
    // we check it here as well to make sure that in case the visitor changed
    // the max_header_length_ (for example after processing the first line)
    // we handle it gracefully.
    if (headers_->GetReadableBytesFromHeaderStream() > max_header_length_) {
      HandleHeadersTooLongError();
      return message_current - original_message_start;
    }

    // Since we know that we won't be writing any more bytes of the header,
    // we tell that to the headers object. The headers object may make
    // more efficient allocation decisions when this is signaled.
    headers_->DoneWritingFromFramer();
    visitor_->OnHeaderInput(headers_->GetReadablePtrFromHeaderStream());

    // Ok, now that we've written everything into our header buffer, it is
    // time to process the header lines (extract proper values for headers
    // which are important for framing).
    ProcessHeaderLines(lines_, false /*is_trailer*/, headers_);
    if (parse_state_ == BalsaFrameEnums::ERROR) {
      return message_current - original_message_start;
    }

    if (use_interim_headers_callback_ &&
        IsInterimResponse(headers_->parsed_response_code()) &&
        headers_->parsed_response_code() != kSwitchingProtocolsStatusCode) {
      // Deliver headers from this interim response but reset everything else to
      // prepare for the next set of headers. Skip 101 Switching Protocols
      // because these are considered final headers for the current protocol.
      visitor_->OnInterimHeaders(
          std::make_unique<BalsaHeaders>(std::move(*headers_)));
      Reset();
      checkpoint = message_start = message_current;
      continue;
    }
    if (continue_headers_ != nullptr &&
        headers_->parsed_response_code_ == kContinueStatusCode) {
      // Save the headers from this 100 Continue response but reset everything
      // else to prepare for the next set of headers.
      BalsaHeaders saved_continue_headers = std::move(*headers_);
      Reset();
      *continue_headers_ = std::move(saved_continue_headers);
      visitor_->ContinueHeaderDone();
      checkpoint = message_start = message_current;
      continue;
    }
    AssignParseStateAfterHeadersHaveBeenParsed();
    if (parse_state_ == BalsaFrameEnums::ERROR) {
      return message_current - original_message_start;
    }
    visitor_->ProcessHeaders(*headers_);
    visitor_->HeaderDone();
    if (parse_state_ == BalsaFrameEnums::MESSAGE_FULLY_READ) {
      visitor_->MessageDone();
    }
    return message_current - original_message_start;
  }
  // If we've gotten to here, it means that we've consumed all of the
  // available input. We need to record whether or not the last character we
  // saw was a '\r' so that a subsequent call to ProcessInput correctly finds
  // a header framing that is split across the two calls.
  last_char_was_slash_r_ = (*(message_end - 1) == '\r');
  QUICHE_DCHECK(message_current >= message_start);
  if (message_current > message_start) {
    headers_->WriteFromFramer(checkpoint, message_current - checkpoint);
  }
  return message_current - original_message_start;
}

size_t BalsaFrame::BytesSafeToSplice() const {
  switch (parse_state_) {
    case BalsaFrameEnums::READING_CHUNK_DATA:
      return chunk_length_remaining_;
    case BalsaFrameEnums::READING_UNTIL_CLOSE:
      return std::numeric_limits<size_t>::max();
    case BalsaFrameEnums::READING_CONTENT:
      return content_length_remaining_;
    default:
      return 0;
  }
}

void BalsaFrame::BytesSpliced(size_t bytes_spliced) {
  switch (parse_state_) {
    case BalsaFrameEnums::READING_CHUNK_DATA:
      if (chunk_length_remaining_ < bytes_spliced) {
        HandleError(BalsaFrameEnums::
                        CALLED_BYTES_SPLICED_AND_EXCEEDED_SAFE_SPLICE_AMOUNT);
        return;
      }
      chunk_length_remaining_ -= bytes_spliced;
      if (chunk_length_remaining_ == 0) {
        parse_state_ = BalsaFrameEnums::READING_CHUNK_TERM;
      }
      return;

    case BalsaFrameEnums::READING_UNTIL_CLOSE:
      return;

    case BalsaFrameEnums::READING_CONTENT:
      if (content_length_remaining_ < bytes_spliced) {
        HandleError(BalsaFrameEnums::
                        CALLED_BYTES_SPLICED_AND_EXCEEDED_SAFE_SPLICE_AMOUNT);
        return;
      }
      content_length_remaining_ -= bytes_spliced;
      if (content_length_remaining_ == 0) {
        parse_state_ = BalsaFrameEnums::MESSAGE_FULLY_READ;
        visitor_->MessageDone();
      }
      return;

    default:
      HandleError(BalsaFrameEnums::CALLED_BYTES_SPLICED_WHEN_UNSAFE_TO_DO_SO);
      return;
  }
}

size_t BalsaFrame::ProcessInput(const char* input, size_t size) {
  const char* current = input;
  const char* on_entry = current;
  const char* end = current + size;

  QUICHE_DCHECK(headers_ != nullptr);
  if (headers_ == nullptr) {
    return 0;
  }

  if (parse_state_ == BalsaFrameEnums::READING_HEADER_AND_FIRSTLINE) {
    const size_t header_length = headers_->GetReadableBytesFromHeaderStream();
    // Yes, we still have to check this here as the user can change the
    // max_header_length amount!
    // Also it is possible that we have reached the maximum allowed header size,
    // and we have more to consume (remember we are still inside
    // READING_HEADER_AND_FIRSTLINE) in which case we directly declare an error.
    if (header_length > max_header_length_ ||
        (header_length == max_header_length_ && size > 0)) {
      HandleHeadersTooLongError();
      return current - input;
    }
    const size_t bytes_to_process =
        std::min(max_header_length_ - header_length, size);
    current += ProcessHeaders(input, bytes_to_process);
    // If we are still reading headers check if we have crossed the headers
    // limit. Note that we check for >= as opposed to >. This is because if
    // header_length_after equals max_header_length_ and we are still in the
    // parse_state_  BalsaFrameEnums::READING_HEADER_AND_FIRSTLINE we know for
    // sure that the headers limit will be crossed later on
    if (parse_state_ == BalsaFrameEnums::READING_HEADER_AND_FIRSTLINE) {
      // Note that headers_ is valid only if we are still reading headers.
      const size_t header_length_after =
          headers_->GetReadableBytesFromHeaderStream();
      if (header_length_after >= max_header_length_) {
        HandleHeadersTooLongError();
      }
    }
    return current - input;
  }

  if (parse_state_ == BalsaFrameEnums::MESSAGE_FULLY_READ ||
      parse_state_ == BalsaFrameEnums::ERROR) {
    // Can do nothing more 'till we're reset.
    return current - input;
  }

  QUICHE_DCHECK_LE(current, end);
  if (current == end) {
    return current - input;
  }

  while (true) {
    switch (parse_state_) {
      case BalsaFrameEnums::READING_CHUNK_LENGTH:
        // In this state we read the chunk length.
        // Note that once we hit a character which is not in:
        // [0-9;A-Fa-f\n], we transition to a different state.
        //
        QUICHE_DCHECK_LE(current, end);
        while (true) {
          if (current == end) {
            visitor_->OnRawBodyInput(
                absl::string_view(on_entry, current - on_entry));
            return current - input;
          }

          const char c = *current;
          ++current;

          static const signed char kBad = -1;
          static const signed char kDelimiter = -2;

          // valid cases:
          //  "09123\n"                      // -> 09123
          //  "09123\r\n"                    // -> 09123
          //  "09123  \n"                    // -> 09123
          //  "09123  \r\n"                  // -> 09123
          //  "09123  12312\n"               // -> 09123
          //  "09123  12312\r\n"             // -> 09123
          //  "09123; foo=bar\n"             // -> 09123
          //  "09123; foo=bar\r\n"           // -> 09123
          //  "FFFFFFFFFFFFFFFF\r\n"         // -> FFFFFFFFFFFFFFFF
          //  "FFFFFFFFFFFFFFFF 22\r\n"      // -> FFFFFFFFFFFFFFFF
          // invalid cases:
          // "[ \t]+[^\n]*\n"
          // "FFFFFFFFFFFFFFFFF\r\n"  (would overflow)
          // "\r\n"
          // "\n"
          signed char addition = kBad;
          // clang-format off
          switch (c) {
            case '0': addition = 0; break;
            case '1': addition = 1; break;
            case '2': addition = 2; break;
            case '3': addition = 3; break;
            case '4': addition = 4; break;
            case '5': addition = 5; break;
            case '6': addition = 6; break;
            case '7': addition = 7; break;
            case '8': addition = 8; break;
            case '9': addition = 9; break;
            case 'a': addition = 0xA; break;
            case 'b': addition = 0xB; break;
            case 'c': addition = 0xC; break;
            case 'd': addition = 0xD; break;
            case 'e': addition = 0xE; break;
            case 'f': addition = 0xF; break;
            case 'A': addition = 0xA; break;
            case 'B': addition = 0xB; break;
            case 'C': addition = 0xC; break;
            case 'D': addition = 0xD; break;
            case 'E': addition = 0xE; break;
            case 'F': addition = 0xF; break;
            case '\t':
            case '\n':
            case '\r':
            case ' ':
            case ';':
              addition = kDelimiter;
              break;
            default:
              // Leave addition == kBad
              break;
          }
          // clang-format on
          if (addition >= 0) {
            chunk_length_character_extracted_ = true;
            size_t length_x_16 = chunk_length_remaining_ * 16;
            const size_t kMaxDiv16 = std::numeric_limits<size_t>::max() / 16;
            if ((chunk_length_remaining_ > kMaxDiv16) ||
                (std::numeric_limits<size_t>::max() - length_x_16) <
                    static_cast<size_t>(addition)) {
              // overflow -- asked for a chunk-length greater than 2^64 - 1!!
              visitor_->OnRawBodyInput(
                  absl::string_view(on_entry, current - on_entry));
              HandleError(BalsaFrameEnums::CHUNK_LENGTH_OVERFLOW);
              return current - input;
            }
            chunk_length_remaining_ = length_x_16 + addition;
            continue;
          }

          if (!chunk_length_character_extracted_ || addition == kBad) {
            // ^[0-9;A-Fa-f][ \t\n] -- was not matched, either because no
            // characters were converted, or an unexpected character was
            // seen.
            visitor_->OnRawBodyInput(
                absl::string_view(on_entry, current - on_entry));
            HandleError(BalsaFrameEnums::INVALID_CHUNK_LENGTH);
            return current - input;
          }

          break;
        }

        --current;
        parse_state_ = BalsaFrameEnums::READING_CHUNK_EXTENSION;
        last_char_was_slash_r_ = false;
        visitor_->OnChunkLength(chunk_length_remaining_);
        continue;

      case BalsaFrameEnums::READING_CHUNK_EXTENSION: {
        // TODO(phython): Convert this scanning to be 16 bytes at a time if
        // there is data to be read.
        const char* extensions_start = current;
        size_t extensions_length = 0;
        QUICHE_DCHECK_LE(current, end);
        while (true) {
          if (current == end) {
            visitor_->OnChunkExtensionInput(
                absl::string_view(extensions_start, extensions_length));
            visitor_->OnRawBodyInput(
                absl::string_view(on_entry, current - on_entry));
            return current - input;
          }
          const char c = *current;
          if (!IsValidChunkExtensionCharacter(c, current, input, end)) {
            HandleError(BalsaFrameEnums::INVALID_CHUNK_EXTENSION);
            return current - input;
          }
          if (current + 1 == end) {
            last_char_was_slash_r_ = c == '\r';
          }
          if (c == '\r' || c == '\n') {
            extensions_length = (extensions_start == current)
                                    ? 0
                                    : current - extensions_start - 1;
          }

          ++current;
          if (c == '\n') {
            break;
          }
        }

        chunk_length_character_extracted_ = false;
        visitor_->OnChunkExtensionInput(
            absl::string_view(extensions_start, extensions_length));

        if (chunk_length_remaining_ != 0) {
          parse_state_ = BalsaFrameEnums::READING_CHUNK_DATA;
          continue;
        }

        HeaderFramingFound('\n');
        parse_state_ = BalsaFrameEnums::READING_LAST_CHUNK_TERM;
        continue;
      }

      case BalsaFrameEnums::READING_CHUNK_DATA:
        while (current < end) {
          if (chunk_length_remaining_ == 0) {
            break;
          }
          // read in the chunk
          size_t bytes_remaining = end - current;
          size_t consumed_bytes = (chunk_length_remaining_ < bytes_remaining)
                                      ? chunk_length_remaining_
                                      : bytes_remaining;
          const char* tmp_current = current + consumed_bytes;
          visitor_->OnRawBodyInput(
              absl::string_view(on_entry, tmp_current - on_entry));
          visitor_->OnBodyChunkInput(
              absl::string_view(current, consumed_bytes));
          on_entry = current = tmp_current;
          chunk_length_remaining_ -= consumed_bytes;
        }

        if (chunk_length_remaining_ == 0) {
          parse_state_ = BalsaFrameEnums::READING_CHUNK_TERM;
          continue;
        }

        visitor_->OnRawBodyInput(
            absl::string_view(on_entry, current - on_entry));
        return current - input;

      case BalsaFrameEnums::READING_CHUNK_TERM:
        QUICHE_DCHECK_LE(current, end);
        while (true) {
          if (current == end) {
            visitor_->OnRawBodyInput(
                absl::string_view(on_entry, current - on_entry));
            return current - input;
          }

          const char c = *current;
          ++current;
          if (c == '\n') {
            break;
          }
        }
        parse_state_ = BalsaFrameEnums::READING_CHUNK_LENGTH;
        continue;

      case BalsaFrameEnums::READING_LAST_CHUNK_TERM:
        QUICHE_DCHECK_LE(current, end);
        while (true) {
          if (current == end) {
            visitor_->OnRawBodyInput(
                absl::string_view(on_entry, current - on_entry));
            return current - input;
          }

          const char c = *current;
          const int32_t framing_found = HeaderFramingFound(c);
          if (framing_found != 0) {
            // TODO(b/433557986) remove these code counts
            if (framing_found == kValidTerm1 && is_request_) {
              QUICHE_CODE_COUNT(balsa_frame_framing_found_valid_term1_request);
            } else if (framing_found == kValidTerm1 && !is_request_) {
              QUICHE_CODE_COUNT(balsa_frame_framing_found_valid_term1_response);
            } else if (framing_found == kValidTerm2 && is_request_) {
              QUICHE_CODE_COUNT(balsa_frame_framing_found_valid_term2_request);
            } else if (framing_found == kValidTerm2 && !is_request_) {
              QUICHE_CODE_COUNT(balsa_frame_framing_found_valid_term2_response);
            }

            // If we've found the end of the chunk, then we're done.
            ++current;

            if (http_validation_policy()
                    .require_chunked_body_end_with_crlf_crlf &&
                framing_found != kValidTerm1) {
              //  https://datatracker.ietf.org/doc/html/rfc9112#name-chunked-transfer-coding
              // The ABNF for chunked coding states that both `last-chunk` _and_
              // `chunked_body` must end with CR_LF, i.e. kValidTerm2 is not
              // allowed.
              HandleError(BalsaFrameEnums::INVALID_CHUNK_FRAMING);
              return current - input;
            }

            parse_state_ = BalsaFrameEnums::MESSAGE_FULLY_READ;
            visitor_->OnRawBodyInput(
                absl::string_view(on_entry, current - on_entry));
            visitor_->MessageDone();
            return current - input;
          }

          // If not, however, since the spec only suggests that the
          // client SHOULD indicate the presence of trailers, we get to
          // *test* that they did or didn't.
          // If all of the bytes we've seen since:
          //   OPTIONAL_WS 0 OPTIONAL_STUFF CRLF
          // are either '\r', or '\n', then we can assume that we don't yet
          // know if we need to parse headers, or if the next byte will make
          // the HeaderFramingFound condition (above) true.
          if (!HeaderFramingMayBeFound()) {
            break;
          }

          // If HeaderFramingMayBeFound(), then we have seen only characters
          // '\r' or '\n'.
          ++current;

          // Lets try again! There is no state change here.
        }

        // If (!HeaderFramingMayBeFound()), then we know that we must be
        // reading the first non CRLF character of a trailer.
        parse_state_ = BalsaFrameEnums::READING_TRAILER;
        visitor_->OnRawBodyInput(
            absl::string_view(on_entry, current - on_entry));
        on_entry = current;
        continue;

      // TODO(yongfa): No leading whitespace is allowed before field-name per
      // RFC2616. Leading whitespace will cause header parsing error too.
      case BalsaFrameEnums::READING_TRAILER:
        while (current < end) {
          const char c = *current;
          ++current;
          ++trailer_length_;
          if (trailers_ != nullptr) {
            // Reuse the header length limit for trailer, which is just a bunch
            // of headers.
            if (trailer_length_ > max_header_length_) {
              --current;
              HandleError(BalsaFrameEnums::TRAILER_TOO_LONG);
              return current - input;
            }
            if (LineFramingFound(c)) {
              trailer_lines_.push_back(
                  std::make_pair(start_of_trailer_line_, trailer_length_));
              start_of_trailer_line_ = trailer_length_;
            }
          }
          if (HeaderFramingFound(c) != 0) {
            parse_state_ = BalsaFrameEnums::MESSAGE_FULLY_READ;
            if (trailers_ != nullptr) {
              trailers_->WriteFromFramer(on_entry, current - on_entry);
              trailers_->DoneWritingFromFramer();
              ProcessHeaderLines(trailer_lines_, true /*is_trailer*/,
                                 trailers_.get());
              if (parse_state_ == BalsaFrameEnums::ERROR) {
                return current - input;
              }
              visitor_->OnTrailers(std::move(trailers_));

              // Allows trailers to be delivered without another call to
              // EnableTrailers() in case the framer is Reset().
              trailers_ = std::make_unique<BalsaHeaders>();
            }
            visitor_->OnTrailerInput(
                absl::string_view(on_entry, current - on_entry));
            visitor_->MessageDone();
            return current - input;
          }
        }
        if (trailers_ != nullptr) {
          trailers_->WriteFromFramer(on_entry, current - on_entry);
        }
        visitor_->OnTrailerInput(
            absl::string_view(on_entry, current - on_entry));
        return current - input;

      case BalsaFrameEnums::READING_UNTIL_CLOSE: {
        const size_t bytes_remaining = end - current;
        if (bytes_remaining > 0) {
          visitor_->OnRawBodyInput(absl::string_view(current, bytes_remaining));
          visitor_->OnBodyChunkInput(
              absl::string_view(current, bytes_remaining));
          current += bytes_remaining;
        }
        return current - input;
      }

      case BalsaFrameEnums::READING_CONTENT:
        while ((content_length_remaining_ != 0u) && current < end) {
          // read in the content
          const size_t bytes_remaining = end - current;
          const size_t consumed_bytes =
              (content_length_remaining_ < bytes_remaining)
                  ? content_length_remaining_
                  : bytes_remaining;
          visitor_->OnRawBodyInput(absl::string_view(current, consumed_bytes));
          visitor_->OnBodyChunkInput(
              absl::string_view(current, consumed_bytes));
          current += consumed_bytes;
          content_length_remaining_ -= consumed_bytes;
        }
        if (content_length_remaining_ == 0) {
          parse_state_ = BalsaFrameEnums::MESSAGE_FULLY_READ;
          visitor_->MessageDone();
        }
        return current - input;

      default:
        // The state-machine should never be in a state that isn't handled
        // above.  This is a glaring logic error, and we should do something
        // drastic to ensure that this gets looked-at and fixed.
        QUICHE_LOG(FATAL) << "Unknown state: " << parse_state_  // COV_NF_LINE
                          << " memory corruption?!";            // COV_NF_LINE
    }
  }
}

void BalsaFrame::HandleHeadersTooLongError() {
  if (parse_truncated_headers_even_when_headers_too_long_) {
    const size_t len = headers_->GetReadableBytesFromHeaderStream();
    const char* stream_begin = headers_->OriginalHeaderStreamBegin();

    if (last_slash_n_idx_ < len && stream_begin[last_slash_n_idx_] != '\r') {
      // We write an end to the truncated line, and a blank line to end the
      // headers, to end up with something that will parse.
      static const absl::string_view kTwoLineEnds = "\r\n\r\n";
      headers_->WriteFromFramer(kTwoLineEnds.data(), kTwoLineEnds.size());

      // This is the last, truncated line.
      lines_.push_back(std::make_pair(last_slash_n_idx_, len + 2));
      // A blank line to end the headers.
      lines_.push_back(std::make_pair(len + 2, len + 4));
    }

    ProcessHeaderLines(lines_, /*is_trailer=*/false, headers_);
  }

  HandleError(BalsaFrameEnums::HEADERS_TOO_LONG);
}

bool BalsaFrame::IsValidChunkExtensionCharacter(char c, const char* current,
                                                const char* begin,
                                                const char* end) {
  if (http_validation_policy_.disallow_lone_cr_in_chunk_extension) {
    // This is a CR character and the next one is not LF.
    const bool cr_followed_by_non_lf =
        c == '\r' && current + 1 < end && *(current + 1) != '\n';
    // The last character processed by the last ProcessInput() call was
    // CR, this is the first character of the current ProcessInput()
    // call, and it is not LF.
    const bool previous_cr_followed_by_non_lf =
        last_char_was_slash_r_ && current == begin && c != '\n';
    if (cr_followed_by_non_lf || previous_cr_followed_by_non_lf) {
      return false;
    }
  }
  const bool prev_c_is_cr =
      current == begin ? last_char_was_slash_r_ : *(current - 1) == '\r';
  // This is a LF char and the previous one was not CR.
  if (c == '\n' && !prev_c_is_cr) {
    if (http_validation_policy_.disallow_lone_lf_in_chunk_extension) {
      return false;
    }
  }
  return true;
}

const int32_t BalsaFrame::kValidTerm1;
const int32_t BalsaFrame::kValidTerm1Mask;
const int32_t BalsaFrame::kValidTerm2;
const int32_t BalsaFrame::kValidTerm2Mask;

}  // namespace quiche

#undef CHAR_LT
#undef CHAR_LE
#undef CHAR_GT
#undef CHAR_GE
#undef QUICHE_DCHECK_CHAR_GE
