Add more BalsaFrameTests for obs-fold and null characters. 1. Test that obs-fold is removed from the beginning or end of a header value. (There is an existing test that documents that it is not removed from the middle.) 2. Test that a null character is not modified in the middle of the header value, in violation with RFC9110, but is stripped from the beginning or end (instead of being replaced by SP, thus also violating the spec). PiperOrigin-RevId: 587567796
diff --git a/quiche/balsa/balsa_frame_test.cc b/quiche/balsa/balsa_frame_test.cc index 5ad9d37..36a8bf8 100644 --- a/quiche/balsa/balsa_frame_test.cc +++ b/quiche/balsa/balsa_frame_test.cc
@@ -4468,16 +4468,24 @@ } TEST_F(HTTPBalsaFrameTest, ContinuationAllowed) { + // See RFC7230 Section 3.2 for the definition of obs-fold: + // https://httpwg.org/specs/rfc7230.html#header.fields. const std::string message = "GET / HTTP/1.1\r\n" - "key: value\n includes continuation\r\n" + "key1: \n value starts with obs-fold\r\n" + "key2: value\n includes obs-fold\r\n" + "key3: value ends in obs-fold \n \r\n" "\r\n"; // TODO(b/314138604): RFC9110 Section 5.5 requires received CR, LF and NUL // characters to be replaced with SP, see // https://www.rfc-editor.org/rfc/rfc9110.html#name-field-values. + // BalsaFrame currently strips (instead of replacing) CR and LF if the value + // starts or ends with obs-fold, and keeps them if they occur in the middle. FakeHeaders fake_headers; - fake_headers.AddKeyValue("key", "value\n includes continuation"); + fake_headers.AddKeyValue("key1", "value starts with obs-fold"); + fake_headers.AddKeyValue("key2", "value\n includes obs-fold"); + fake_headers.AddKeyValue("key3", "value ends in obs-fold"); EXPECT_CALL(visitor_mock_, ProcessHeaders(fake_headers)); EXPECT_EQ(message.size(), @@ -4492,7 +4500,7 @@ const std::string message = "GET / HTTP/1.1\r\n" - "key: value\n includes continuation\r\n" + "key: value\n includes obs-fold\r\n" "\r\n"; EXPECT_EQ(message.size(), balsa_frame_.ProcessInput(message.data(), message.size())); @@ -4500,6 +4508,32 @@ EXPECT_EQ(BalsaFrameEnums::INVALID_HEADER_FORMAT, balsa_frame_.ErrorCode()); } +TEST_F(HTTPBalsaFrameTest, NullInValue) { + constexpr absl::string_view null_string("\0", 1); + const std::string message = + absl::StrCat("GET / HTTP/1.1\r\n", // + "key1: ", null_string, "value starts with null\r\n", // + "key2: value ", null_string, "includes null\r\n", // + "key3: value ends in null", null_string, "\r\n", // + "\r\n"); + + // TODO(b/314138604): RFC9110 Section 5.5 requires received CR, LF and NUL + // characters to be replaced with SP, see + // https://www.rfc-editor.org/rfc/rfc9110.html#name-field-values. + // BalsaFrame currently strips (instead of replacing) NUL at the beginning or + // end of the header value, but keeps it if it occurs in the middle. + FakeHeaders fake_headers; + fake_headers.AddKeyValue("key1", "value starts with null"); + fake_headers.AddKeyValue( + "key2", absl::StrCat("value ", null_string, "includes null")); + fake_headers.AddKeyValue("key3", "value ends in null"); + EXPECT_CALL(visitor_mock_, ProcessHeaders(fake_headers)); + + EXPECT_EQ(message.size(), + balsa_frame_.ProcessInput(message.data(), message.size())); + EXPECT_FALSE(balsa_frame_.Error()); +} + } // namespace } // namespace test