static bool validateHeaderValue()

in proxygen/lib/http/codec/CodecUtil.h [111:185]


  static bool validateHeaderValue(folly::ByteRange value, CtlEscapeMode mode) {
    bool escape = false;
    bool quote = false;
    enum {
      lws_none,
      lws_expect_nl,
      lws_expect_ws1,
      lws_expect_ws2
    } state = lws_none;

    for (auto p = std::begin(value); p != std::end(value); ++p) {
      if (escape) {
        escape = false;
        if (mode == COMPLIANT) {
          // prev char escaped.  Turn off escape and go to next char
          // COMPLIANT mode only
          assert(quote);
          continue;
        }
      }
      switch (state) {
        case lws_none:
          switch (*p) {
            case '\\':
              if (quote) {
                escape = true;
              }
              break;
            case '\"':
              quote = !quote;
              break;
            case '\r':
              state = lws_expect_nl;
              break;
            default:
              if ((*p < 0x20 && *p != '\t') || (*p == 0x7f) ||
                  (*p > 0x7f && mode == STRICT)) {
                // unexpected ctl per rfc2616, HT OK
                return false;
              }
              break;
          }
          break;
        case lws_expect_nl:
          if (*p != '\n') {
            // unescaped \r must be LWS
            return false;
          }
          state = lws_expect_ws1;
          break;
        case lws_expect_ws1:
          if (*p != ' ' && *p != '\t') {
            // unescaped \r\n must be LWS
            return false;
          }
          state = lws_expect_ws2;
          break;
        case lws_expect_ws2:
          if (*p != ' ' && *p != '\t') {
            // terminated LWS
            state = lws_none;
            // check this char again
            p--;
          }
          break;
      }
    }
    // Unterminated quotes are OK, since the value can be* TEXT which treats
    // the " like any other char.
    // Unterminated escapes are bad because it will escape the next character
    // when converting to HTTP
    // Unterminated LWS (dangling \r or \r\n) is bad because it could
    // prematurely terminate the headers when converting to HTTP
    return !escape && (state == lws_none || state == lws_expect_ws2);
  }