Extracts out header value validation into a separate static method. This new method can be used as a replacement for a similar function in nghttp2. PiperOrigin-RevId: 500826813
diff --git a/quiche/http2/adapter/header_validator.cc b/quiche/http2/adapter/header_validator.cc index e4874f2..e474558 100644 --- a/quiche/http2/adapter/header_validator.cc +++ b/quiche/http2/adapter/header_validator.cc
@@ -64,16 +64,6 @@ return AllCharsInMap(name, valid_chars); } -bool IsValidHeaderValue(absl::string_view value, ObsTextOption option) { - static const CharMap valid_chars = - BuildValidCharMap(kHttp2HeaderValueAllowedChars); - static const CharMap valid_chars_with_obs_text = - AllowObsText(BuildValidCharMap(kHttp2HeaderValueAllowedChars)); - return AllCharsInMap(value, option == ObsTextOption::kAllow - ? valid_chars_with_obs_text - : valid_chars); -} - bool IsValidStatus(absl::string_view status) { static const CharMap valid_chars = BuildValidCharMap(kHttp2StatusValueAllowedChars); @@ -246,7 +236,17 @@ return false; } -/* static */ +bool HeaderValidator::IsValidHeaderValue(absl::string_view value, + ObsTextOption option) { + static const CharMap valid_chars = + BuildValidCharMap(kHttp2HeaderValueAllowedChars); + static const CharMap valid_chars_with_obs_text = + AllowObsText(BuildValidCharMap(kHttp2HeaderValueAllowedChars)); + return AllCharsInMap(value, option == ObsTextOption::kAllow + ? valid_chars_with_obs_text + : valid_chars); +} + bool HeaderValidator::IsValidAuthority(absl::string_view authority) { static const CharMap valid_chars = BuildValidCharMap(kValidAuthorityChars); return AllCharsInMap(authority, valid_chars);
diff --git a/quiche/http2/adapter/header_validator.h b/quiche/http2/adapter/header_validator.h index 6095c7d..a6070db 100644 --- a/quiche/http2/adapter/header_validator.h +++ b/quiche/http2/adapter/header_validator.h
@@ -25,6 +25,11 @@ // present for the given header type. bool FinishHeaderBlock(HeaderType type) override; + // Returns whether `value` is valid according to RFC 9110 Section 5.5 and RFC + // 9112 Section 8.2.1. + static bool IsValidHeaderValue(absl::string_view value, + ObsTextOption ops_text_option); + // Returns whether `authority` is valid according to RFC 3986 Section 3.2. static bool IsValidAuthority(absl::string_view authority);
diff --git a/quiche/http2/adapter/header_validator_test.cc b/quiche/http2/adapter/header_validator_test.cc index a329f12..3dfbd96 100644 --- a/quiche/http2/adapter/header_validator_test.cc +++ b/quiche/http2/adapter/header_validator_test.cc
@@ -85,34 +85,48 @@ // These characters should be allowed. (Not exhaustive.) for (const char* c : {"!", "3", "a", "_", "|", "~", "\\", "<", ";", "[", "=", "A", "\t"}) { + const std::string value = absl::StrCat("val", c, "ue"); + EXPECT_TRUE( + HeaderValidator::IsValidHeaderValue(value, ObsTextOption::kDisallow)); HeaderValidator::HeaderStatus status = - v.ValidateSingleHeader("name", absl::StrCat("val", c, "ue")); + v.ValidateSingleHeader("name", value); EXPECT_EQ(HeaderValidator::HEADER_OK, status); } // These should not. for (const char* c : {"\r", "\n"}) { + const std::string value = absl::StrCat("val", c, "ue"); + EXPECT_FALSE( + HeaderValidator::IsValidHeaderValue(value, ObsTextOption::kDisallow)); HeaderValidator::HeaderStatus status = - v.ValidateSingleHeader("name", absl::StrCat("val", c, "ue")); + v.ValidateSingleHeader("name", value); EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID, status); } // Test nul separately. { + const std::string value("val\0ue", 6); + EXPECT_FALSE( + HeaderValidator::IsValidHeaderValue(value, ObsTextOption::kDisallow)); HeaderValidator::HeaderStatus status = - v.ValidateSingleHeader("name", absl::string_view("val\0ue", 6)); + v.ValidateSingleHeader("name", value); EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID, status); } { + const std::string obs_text_value = "val\xa9ue"; // Test that obs-text is disallowed by default. EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID, - v.ValidateSingleHeader("name", "val\xa9ue")); + v.ValidateSingleHeader("name", obs_text_value)); // Test that obs-text is disallowed when configured. v.SetObsTextOption(ObsTextOption::kDisallow); + EXPECT_FALSE(HeaderValidator::IsValidHeaderValue(obs_text_value, + ObsTextOption::kDisallow)); EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID, - v.ValidateSingleHeader("name", "val\xa9ue")); + v.ValidateSingleHeader("name", obs_text_value)); // Test that obs-text is allowed when configured. v.SetObsTextOption(ObsTextOption::kAllow); + EXPECT_TRUE(HeaderValidator::IsValidHeaderValue(obs_text_value, + ObsTextOption::kAllow)); EXPECT_EQ(HeaderValidator::HEADER_OK, - v.ValidateSingleHeader("name", "val\xa9ue")); + v.ValidateSingleHeader("name", obs_text_value)); } }