Signal error in HttpDecoder if frames have disallowed extra payload. gfe-relnote: n/a, change to QUIC v99-only code. Protected by existing disabled gfe2_reloadable_flag_quic_enable_version_99. PiperOrigin-RevId: 262344819 Change-Id: Ie0e82fc87f9da8e2533a177a062f58edefe35cb7
diff --git a/quic/core/http/http_decoder.cc b/quic/core/http/http_decoder.cc index 1a89324..227a839 100644 --- a/quic/core/http/http_decoder.cc +++ b/quic/core/http/http_decoder.cc
@@ -314,6 +314,11 @@ RaiseError(QUIC_INVALID_FRAME_DATA, "Unable to read push_id"); return false; } + if (!reader.IsDoneReading()) { + RaiseError(QUIC_INVALID_FRAME_DATA, + "Superfluous data in CANCEL_PUSH frame."); + return false; + } continue_processing = visitor_->OnCancelPushFrame(frame); break; } @@ -344,6 +349,11 @@ RaiseError(QUIC_INVALID_FRAME_DATA, "Unable to read GOAWAY stream_id"); return false; } + if (!reader.IsDoneReading()) { + RaiseError(QUIC_INVALID_FRAME_DATA, + "Superfluous data in GOAWAY frame."); + return false; + } frame.stream_id = static_cast<QuicStreamId>(stream_id); continue_processing = visitor_->OnGoAwayFrame(frame); break; @@ -357,6 +367,11 @@ RaiseError(QUIC_INVALID_FRAME_DATA, "Unable to read push_id"); return false; } + if (!reader.IsDoneReading()) { + RaiseError(QUIC_INVALID_FRAME_DATA, + "Superfluous data in MAX_PUSH_ID frame."); + return false; + } continue_processing = visitor_->OnMaxPushIdFrame(frame); break; } @@ -369,6 +384,11 @@ RaiseError(QUIC_INVALID_FRAME_DATA, "Unable to read push_id"); return false; } + if (!reader.IsDoneReading()) { + RaiseError(QUIC_INVALID_FRAME_DATA, + "Superfluous data in DUPLICATE_PUSH frame."); + return false; + } continue_processing = visitor_->OnDuplicatePushFrame(frame); break; } @@ -482,12 +502,12 @@ if (!reader->ReadUInt8(&frame->weight)) { // TODO(b/124216424): Use HTTP_MALFORMED_FRAME. RaiseError(QUIC_INVALID_FRAME_DATA, - "Unable to read priority frame weight."); + "Unable to read PRIORITY frame weight."); return false; } if (!reader->IsDoneReading()) { // TODO(b/124216424): Use HTTP_MALFORMED_FRAME. - RaiseError(QUIC_INVALID_FRAME_DATA, "Superfluous data in priority frame."); + RaiseError(QUIC_INVALID_FRAME_DATA, "Superfluous data in PRIORITY frame."); return false; } return true;
diff --git a/quic/core/http/http_decoder_test.cc b/quic/core/http/http_decoder_test.cc index 313af62..cbadf3b 100644 --- a/quic/core/http/http_decoder_test.cc +++ b/quic/core/http/http_decoder_test.cc
@@ -388,11 +388,11 @@ {payload1, 0, "Unable to read PRIORITY frame flags."}, {payload1, 1, "Unable to read prioritized_element_id."}, {payload1, 2, "Unable to read element_dependency_id."}, - {payload1, 3, "Unable to read priority frame weight."}, - {payload1, 5, "Superfluous data in priority frame."}, + {payload1, 3, "Unable to read PRIORITY frame weight."}, + {payload1, 5, "Superfluous data in PRIORITY frame."}, {payload2, 0, "Unable to read PRIORITY frame flags."}, - {payload2, 1, "Unable to read priority frame weight."}, - {payload2, 3, "Superfluous data in priority frame."}, + {payload2, 1, "Unable to read PRIORITY frame weight."}, + {payload2, 3, "Superfluous data in PRIORITY frame."}, }; for (const auto& test_data : kTestData) { @@ -837,6 +837,11 @@ "\x01" // length "\x40", // first byte of two-byte varint push id "Unable to read push_id"}, + {"\x03" // type (CANCEL_PUSH) + "\x04" // length + "\x05" // valid push id + "foo", // superfluous data + "Superfluous data in CANCEL_PUSH frame."}, {"\x05" // type (PUSH_PROMISE) "\x01" // length "\x40", // first byte of two-byte varint push id @@ -845,14 +850,29 @@ "\x01" // length "\x40", // first byte of two-byte varint push id "Unable to read push_id"}, + {"\x0D" // type (MAX_PUSH_ID) + "\x04" // length + "\x05" // valid push id + "foo", // superfluous data + "Superfluous data in MAX_PUSH_ID frame."}, {"\x0E" // type (DUPLICATE_PUSH) "\x01" // length "\x40", // first byte of two-byte varint push id "Unable to read push_id"}, + {"\x0E" // type (DUPLICATE_PUSH) + "\x04" // length + "\x05" // valid push id + "foo", // superfluous data + "Superfluous data in DUPLICATE_PUSH frame."}, {"\x07" // type (GOAWAY) "\x01" // length "\x40", // first byte of two-byte varint stream id - "Unable to read GOAWAY stream_id"}}; + "Unable to read GOAWAY stream_id"}, + {"\x07" // type (GOAWAY) + "\x04" // length + "\x05" // valid stream id + "foo", // superfluous data + "Superfluous data in GOAWAY frame."}}; for (const auto& test_data : kTestData) { {