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));
   }
 }