From 48c1f2a4fe529084ddbd4f6a0cb05c81d2086962 Mon Sep 17 00:00:00 2001 From: Rich Logan Date: Wed, 18 Feb 2026 12:41:10 +0000 Subject: [PATCH 1/3] Fix double encode --- include/quicr/detail/ctrl_message_types.h | 9 ++++-- test/moq_ctrl_messages.cpp | 34 +++++++++++++++++++++++ 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/include/quicr/detail/ctrl_message_types.h b/include/quicr/detail/ctrl_message_types.h index 2fdc9db9..ff7e54cf 100644 --- a/include/quicr/detail/ctrl_message_types.h +++ b/include/quicr/detail/ctrl_message_types.h @@ -523,8 +523,9 @@ namespace quicr::messages { { if constexpr (std::is_arithmetic_v || std::is_enum_v) { if (static_cast(type) % 2 == 0) { - UintVar u_value(static_cast(value)); - parameters.push_back({ type, Bytes{ u_value.begin(), u_value.end() } }); + const std::uint64_t val = static_cast(value); + auto* val_bytes = reinterpret_cast(&val); + parameters.push_back({ type, Bytes{ val_bytes, val_bytes + sizeof(val) } }); return *this; } } @@ -584,7 +585,9 @@ namespace quicr::messages { if constexpr (std::is_arithmetic_v) { if (static_cast(type) % 2 == 0) { - return static_cast(UintVar(bytes).Get()); + std::uint64_t val = 0; + std::memcpy(&val, bytes.data(), std::min(bytes.size(), sizeof(val))); + return static_cast(val); } } diff --git a/test/moq_ctrl_messages.cpp b/test/moq_ctrl_messages.cpp index 8c019870..7651dba7 100644 --- a/test/moq_ctrl_messages.cpp +++ b/test/moq_ctrl_messages.cpp @@ -810,3 +810,37 @@ TEST_CASE("uint16_t encode/decode") { IntegerEncodeDecode(true); } + +TEST_CASE("KeyValuePair even-type round-trip preserves values") +{ + const std::vector test_values = { + 0, 1, + 63, // Max 1-byte varint + 64, // Min 2-byte varint + 127, 128, 255, + 16383, // Max 2-byte varint + 16384, // Min 4-byte varint + 100000, + }; + + for (const auto value : test_values) { + CAPTURE(value); + + // Create a ParameterList with the value + Parameters params; + params.Add(ParameterType::kDeliveryTimeout, value); + + // Serialize to wire format + Bytes buffer; + buffer << params; + + // Deserialize + Parameters out; + BytesSpan span{ buffer }; + span >> out; + + // Get() should return the original value + CHECK_NOTHROW(out.Get(ParameterType::kDeliveryTimeout)); + CHECK_EQ(out.Get(ParameterType::kDeliveryTimeout), value); + } +} From fb20a36b07f82b321ceb1fcfff3073cc8f569eb2 Mon Sep 17 00:00:00 2001 From: Rich Logan Date: Wed, 18 Feb 2026 15:08:45 +0000 Subject: [PATCH 2/3] Double encode for track extensions --- include/quicr/detail/ctrl_message_types.h | 15 +++++++++--- test/moq_ctrl_messages.cpp | 30 +++++++++++++++++++++++ 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/include/quicr/detail/ctrl_message_types.h b/include/quicr/detail/ctrl_message_types.h index ff7e54cf..45b938fb 100644 --- a/include/quicr/detail/ctrl_message_types.h +++ b/include/quicr/detail/ctrl_message_types.h @@ -408,8 +408,9 @@ namespace quicr::messages { { if constexpr (std::is_arithmetic_v || std::is_enum_v) { if (static_cast(type) % 2 == 0) { - UintVar u_value(static_cast(value)); - return Bytes{ u_value.begin(), u_value.end() }; + const std::uint64_t val = static_cast(value); + auto* val_bytes = reinterpret_cast(&val); + return Bytes{ val_bytes, val_bytes + sizeof(val) }; } } @@ -459,7 +460,10 @@ namespace quicr::messages { { if constexpr (std::is_arithmetic_v) { if (static_cast(type) % 2 == 0) { - return static_cast(UintVar(extensions.at(static_cast(type))).Get()); + std::uint64_t val = 0; + const auto& bytes = extensions.at(static_cast(type)); + std::memcpy(&val, bytes.data(), std::min(bytes.size(), sizeof(val))); + return static_cast(val); } } @@ -477,7 +481,10 @@ namespace quicr::messages { { if constexpr (std::is_arithmetic_v) { if (static_cast(type) % 2 == 0) { - return static_cast(UintVar(immutable_extensions.at(static_cast(type))).Get()); + std::uint64_t val = 0; + const auto& bytes = immutable_extensions.at(static_cast(type)); + std::memcpy(&val, bytes.data(), std::min(bytes.size(), sizeof(val))); + return static_cast(val); } } diff --git a/test/moq_ctrl_messages.cpp b/test/moq_ctrl_messages.cpp index 7651dba7..f69e70a9 100644 --- a/test/moq_ctrl_messages.cpp +++ b/test/moq_ctrl_messages.cpp @@ -844,3 +844,33 @@ TEST_CASE("KeyValuePair even-type round-trip preserves values") CHECK_EQ(out.Get(ParameterType::kDeliveryTimeout), value); } } + +TEST_CASE("TrackExtensions even-type round-trip preserves values") +{ + const std::vector test_values = { + 0, 1, + 63, // Max 1-byte varint + 64, // Min 2-byte varint + 127, 128, 255, + 16383, // Max 2-byte varint + 16384, // Min 4-byte varint + 100000, + }; + + for (const auto value : test_values) { + CAPTURE(value); + + TrackExtensions ext; + ext.Add(ExtensionType::kDeliveryTimeout, value); + + Bytes buffer; + buffer << ext; + + TrackExtensions out; + BytesSpan span{ buffer }; + span >> out; + + CHECK_NOTHROW(out.Get(ExtensionType::kDeliveryTimeout)); + CHECK_EQ(out.Get(ExtensionType::kDeliveryTimeout), value); + } +} From 788962ac121a750944d49fe3e1db8f5dbf253bda Mon Sep 17 00:00:00 2001 From: Rich Logan Date: Wed, 18 Feb 2026 15:13:46 +0000 Subject: [PATCH 3/3] Add encoded check also --- test/moq_ctrl_messages.cpp | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/test/moq_ctrl_messages.cpp b/test/moq_ctrl_messages.cpp index f69e70a9..37610b0f 100644 --- a/test/moq_ctrl_messages.cpp +++ b/test/moq_ctrl_messages.cpp @@ -826,20 +826,24 @@ TEST_CASE("KeyValuePair even-type round-trip preserves values") for (const auto value : test_values) { CAPTURE(value); - // Create a ParameterList with the value Parameters params; params.Add(ParameterType::kDeliveryTimeout, value); - // Serialize to wire format Bytes buffer; buffer << params; - // Deserialize + // Should have encoded as uintvar. + UintVar expected(value); + Bytes expected_bytes{ expected.begin(), expected.end() }; + REQUIRE(buffer.size() >= expected_bytes.size()); + Bytes tail(buffer.end() - expected_bytes.size(), buffer.end()); + CHECK_EQ(tail, expected_bytes); + Parameters out; BytesSpan span{ buffer }; span >> out; - // Get() should return the original value + // Roundtrip. CHECK_NOTHROW(out.Get(ParameterType::kDeliveryTimeout)); CHECK_EQ(out.Get(ParameterType::kDeliveryTimeout), value); } @@ -866,10 +870,18 @@ TEST_CASE("TrackExtensions even-type round-trip preserves values") Bytes buffer; buffer << ext; + // Should have been encoded as uintvar. + UintVar expected(value); + Bytes expected_bytes{ expected.begin(), expected.end() }; + REQUIRE(buffer.size() >= expected_bytes.size()); + Bytes tail(buffer.end() - expected_bytes.size(), buffer.end()); + CHECK_EQ(tail, expected_bytes); + TrackExtensions out; BytesSpan span{ buffer }; span >> out; + // Roundtrip. CHECK_NOTHROW(out.Get(ExtensionType::kDeliveryTimeout)); CHECK_EQ(out.Get(ExtensionType::kDeliveryTimeout), value); }