Fix error in MoQT Relative Location encoding. Not in production PiperOrigin-RevId: 606996381
diff --git a/quiche/quic/moqt/moqt_framer.cc b/quiche/quic/moqt/moqt_framer.cc index 2c46476..61caf1e 100644 --- a/quiche/quic/moqt/moqt_framer.cc +++ b/quiche/quic/moqt/moqt_framer.cc
@@ -91,7 +91,7 @@ } return writer.WriteVarInt62(loc->absolute_value); } - if (loc->relative_value < 0) { + if (loc->relative_value <= 0) { if (!writer.WriteVarInt62(static_cast<uint64_t>( MoqtSubscribeLocationMode::kRelativePrevious))) { return false; @@ -103,7 +103,7 @@ static_cast<uint64_t>(MoqtSubscribeLocationMode::kRelativeNext))) { return false; } - return writer.WriteVarInt62(static_cast<uint64_t>(loc->relative_value)); + return writer.WriteVarInt62(static_cast<uint64_t>(loc->relative_value - 1)); } } // namespace
diff --git a/quiche/quic/moqt/moqt_parser.cc b/quiche/quic/moqt/moqt_parser.cc index b8754f2..ac72183 100644 --- a/quiche/quic/moqt/moqt_parser.cc +++ b/quiche/quic/moqt/moqt_parser.cc
@@ -600,7 +600,7 @@ loc = MoqtSubscribeLocation(false, -1 * static_cast<int64_t>(ui64)); break; case MoqtSubscribeLocationMode::kRelativeNext: - loc = MoqtSubscribeLocation(false, static_cast<int64_t>(ui64)); + loc = MoqtSubscribeLocation(false, static_cast<int64_t>(ui64) + 1); break; default: ParseError("Unknown location mode");
diff --git a/quiche/quic/moqt/moqt_parser_test.cc b/quiche/quic/moqt/moqt_parser_test.cc index c0f1e9b..278c39f 100644 --- a/quiche/quic/moqt/moqt_parser_test.cc +++ b/quiche/quic/moqt/moqt_parser_test.cc
@@ -10,6 +10,7 @@ #include <memory> #include <optional> #include <string> +#include <utility> #include <vector> #include "absl/strings/string_view.h" @@ -860,4 +861,31 @@ EXPECT_FALSE(visitor_.parsing_error_.has_value()); } +TEST_F(MoqtMessageSpecificTest, RelativeLocation) { + MoqtParser parser(kRawQuic, visitor_); + char subscribe[] = { + 0x03, 0x01, 0x02, // id and alias + 0x03, 0x66, 0x6f, 0x6f, // track_namespace = "foo" + 0x04, 0x61, 0x62, 0x63, 0x64, // track_name = "abcd" + 0x02, 0x00, // start_group = 0 (relative previous) + 0x03, 0x00, // start_object = 1 (relative next) + 0x00, // end_group = none + 0x00, // end_object = none +#ifdef MOQT_AUTH_INFO + 0x01, // 1 parameter + 0x02, 0x03, 0x62, 0x61, 0x72, // authorization_info = "bar" +#endif + }; + parser.ProcessData(absl::string_view(subscribe, sizeof(subscribe)), false); + EXPECT_EQ(visitor_.messages_received_, 1); + MoqtSubscribe message = std::get<MoqtSubscribe>(*visitor_.last_message_); + EXPECT_FALSE(visitor_.parsing_error_.has_value()); + ASSERT_TRUE(message.start_group.has_value()); + ASSERT_FALSE(message.start_group->absolute); + EXPECT_EQ(message.start_group->relative_value, 0); + ASSERT_TRUE(message.start_object.has_value()); + ASSERT_FALSE(message.start_object->absolute); + EXPECT_EQ(message.start_object->relative_value, 1); +} + } // namespace moqt::test