diff --git a/quiche/web_transport/encapsulated/encapsulated_web_transport.cc b/quiche/web_transport/encapsulated/encapsulated_web_transport.cc index a879870da..a9ee48309 100644 --- a/quiche/web_transport/encapsulated/encapsulated_web_transport.cc +++ b/quiche/web_transport/encapsulated/encapsulated_web_transport.cc @@ -556,8 +556,9 @@ Stream::ReadResult EncapsulatedSession::InnerStream::Read( memcpy(output.data(), read.data.data(), size_to_read); output = output.subspan(size_to_read); } - bool fin_consumed = SkipBytes(total_size); - return ReadResult{total_size, fin_consumed}; + const size_t bytes_read = total_size - output.size(); + bool fin_consumed = SkipBytes(bytes_read); + return ReadResult{bytes_read, fin_consumed}; } Stream::ReadResult EncapsulatedSession::InnerStream::Read(std::string* output) { const size_t total_size = ReadableBytes(); diff --git a/quiche/web_transport/encapsulated/encapsulated_web_transport_test.cc b/quiche/web_transport/encapsulated/encapsulated_web_transport_test.cc index fe9632473..ec3fd831e 100644 --- a/quiche/web_transport/encapsulated/encapsulated_web_transport_test.cc +++ b/quiche/web_transport/encapsulated/encapsulated_web_transport_test.cc @@ -478,6 +478,31 @@ TEST_F(EncapsulatedWebTransportTest, FinRead) { EXPECT_TRUE(read.fin); } +TEST_F(EncapsulatedWebTransportTest, ReadIntoOversizedBuffer) { + std::unique_ptr session = + CreateTransport(Perspective::kClient); + DefaultHandshakeForClient(*session); + EXPECT_CALL(*visitor_, OnIncomingBidirectionalStreamAvailable()); + ProcessIncomingCapsule( + quiche::WebTransportStreamDataCapsule{1, "abcd", false}); + Stream* stream = session->AcceptIncomingBidirectionalStream(); + ASSERT_TRUE(stream != nullptr); + EXPECT_EQ(stream->ReadableBytes(), 4u); + + std::array buffer; + Stream::ReadResult read = stream->Read(absl::MakeSpan(buffer)); + EXPECT_EQ(read.bytes_read, 4u); + EXPECT_FALSE(read.fin); + EXPECT_EQ(absl::string_view(buffer.data(), read.bytes_read), "abcd"); + EXPECT_EQ(stream->ReadableBytes(), 0u); + + ProcessIncomingCapsule(quiche::WebTransportStreamDataCapsule{1, "ef", true}); + read = stream->Read(absl::MakeSpan(buffer)); + EXPECT_EQ(read.bytes_read, 2u); + EXPECT_TRUE(read.fin); + EXPECT_EQ(absl::string_view(buffer.data(), read.bytes_read), "ef"); +} + TEST_F(EncapsulatedWebTransportTest, LargeRead) { std::unique_ptr session = CreateTransport(Perspective::kClient);