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