Skip to content

Conversation

@kixelated
Copy link
Collaborator

@kixelated kixelated commented Nov 2, 2025

Summary by CodeRabbit

  • Refactor
    • Unified parameter handling across protocol variants for consistency during handshakes and setup.
    • Changed parameter encoding/decoding to use a parity-based format (different handling for even vs odd IDs), affecting how parameter values are serialized.
    • Lightweight mode no longer exposes direct accessor methods for parameter entries; internal fields are surfaced differently.
    • Parsing now accepts and ignores parameters in places where they are not retained.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 2, 2025

Walkthrough

The parameters module and re-export were removed from coding. A new ietf::parameters module adds pub struct Parameters(HashMap<u64, Vec<u8>>) with custom Encode/Decode: max 64 entries, no duplicate kinds, even kinds store varint bytes directly and odd kinds store length-prefixed bytes. Several ietf/* and lite/* files import Parameters from their respective modules; lite gains a parameters module and its impl had get/set accessors removed. session.rs was updated to use ietf::Parameters and adjusted parameter indices.

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The PR title "Fix IETF parameter parsing." directly corresponds to the primary changes in this pull request. The changeset reorganizes the Parameters module from the coding namespace to the ietf namespace (more architecturally appropriate for the IETF protocol) and substantially updates the encoding/decoding logic with parity-based handling where even-ID parameters use direct varint byte encoding and odd-ID parameters use length-prefixed encoding. The title is concise and specific enough to convey that this PR addresses corrections to IETF parameter encoding/decoding, which aligns well with the actual modifications across both Rust and JavaScript implementations.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix-parameters

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9e01e68 and bd5de00.

📒 Files selected for processing (2)
  • js/moq/src/ietf/parameters.ts (3 hunks)
  • rs/moq/src/lite/parameters.rs (0 hunks)
💤 Files with no reviewable changes (1)
  • rs/moq/src/lite/parameters.rs
🧰 Additional context used
🧬 Code graph analysis (1)
js/moq/src/ietf/parameters.ts (1)
js/moq/src/stream.ts (3)
  • Reader (53-207)
  • size (97-107)
  • size (110-119)
🔇 Additional comments (4)
js/moq/src/ietf/parameters.ts (4)

2-2: LGTM: Import addition is correct.

The setVint62 import is necessary for re-encoding varint values during decoding of even-ID parameters.


71-73: LGTM: Duplicate parameter detection is correct.

The duplicate ID check is properly placed after decoding the value but before insertion, with a clear error message.


29-45: ****

The review comment describes code that does not exist in the current state of the file. The encode() method shown in the review (with parity-based branching for even/odd IDs) is not present in js/moq/src/ietf/parameters.ts.

The actual current implementation (lines 29-36) uses uniform encoding for all parameters:

async encode(w: Writer) {
    await w.u53(this.entries.size);
    for (const [id, value] of this.entries) {
        await w.u62(id);
        await w.u53(value.length);  // Always writes length prefix
        await w.write(value);
    }
}

Since the code differs fundamentally from what is described in the review comment, the concerns raised about even-ID varint encoding validation and the proposed fixes do not apply. Verify whether this review comment is intended for a different code state or a proposed change that was not yet applied.

Likely an incorrect or invalid review comment.


47-79: Original review comment is incorrect and should be dismissed.

Verification confirms the code is correct:

  1. setVint62 already returns properly-sized bytes: The function branches on value size (1, 2, 4, or 8 bytes) and returns the correctly-sized Uint8Array through setUint8, setUint16, setUint32, or setUint64—not always 8 bytes. The buffer allocation and re-encoding approach is sound.

  2. No parameter count limit exists: The IETF MOQ Transport specification states "The number of parameters in a message is not specifically limited, but the total length of a control message is limited to 2^16-1 bytes." There is no 64-parameter enforcement requirement to add.

The decode logic is correct as written. The duplicate ID check (lines 71–73) is appropriate, and the varint encoding/decoding flow handles parity correctly per the protocol spec.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
rs/moq/src/ietf/publish_namespace.rs (1)

213-223: Update test to expect successful decoding with parameters.

The test test_announce_rejects_parameters expects decoding to fail (line 221: assert!(result.is_err())), but this expectation is outdated. The Parameters::decode implementation at rs/moq/src/ietf/parameters.rs:10-49 successfully decodes non-empty parameter counts. It only returns errors when the count exceeds MAX_PARAMS or duplicate keys are encountered—not for num_params = 1.

Since the PublishNamespace decoder at line 35 calls Parameters::decode(r)? without special rejection logic, the test should be updated to expect Ok and verify the decoded message structure:

fn test_announce_rejects_parameters() {
	#[rustfmt::skip]
	let invalid_bytes = vec![
		0x01, // namespace length
		0x04, 0x74, 0x65, 0x73, 0x74, // "test"
		0x01, // num_params = 1
	];

	let result: Result<PublishNamespace, _> = decode_message(&invalid_bytes);
	assert!(result.is_ok());
}

Alternatively, rename the test to reflect that parameters are successfully ignored, or remove it if parameter decoding is no longer a concern.

🧹 Nitpick comments (1)
rs/moq/src/ietf/parameters.rs (1)

71-77: Add typed setters for even/odd parameter kinds

set currently trusts callers to hand-encode the Value field, even when the kind is even. The IETF draft requires even kinds to be a single varint with canonical QUIC encoding (correct prefix bits, minimum length). Hand-rolling those bytes is very easy to get wrong, and one stray slice like [0x00, 0x3f] will trip a KEY_VALUE_FORMATTING_ERROR on the wire. Let’s give callers a safe helper that does the varint encoding internally (and a separate helper for odd kinds) so misuse isn’t possible.

-	pub fn set(&mut self, kind: u64, value: Vec<u8>) {
-		self.0.insert(kind, value);
-	}
+	pub fn set_varint(&mut self, kind: u64, value: u64) {
+		debug_assert_eq!(kind % 2, 0, "set_varint expects an even parameter kind");
+
+		let mut encoded = Vec::new();
+		value.encode(&mut encoded);
+		self.0.insert(kind, encoded);
+	}
+
+	pub fn set_bytes(&mut self, kind: u64, value: Vec<u8>) {
+		debug_assert_eq!(kind % 2, 1, "set_bytes expects an odd parameter kind");
+		self.0.insert(kind, value);
+	}

(After adding these, migrate call sites like Session::connect/accept to use set_varint for even code points and set_bytes for odd ones.)

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 29415ab and 9e01e68.

📒 Files selected for processing (14)
  • rs/moq/src/coding/mod.rs (0 hunks)
  • rs/moq/src/ietf/fetch.rs (1 hunks)
  • rs/moq/src/ietf/mod.rs (2 hunks)
  • rs/moq/src/ietf/parameters.rs (1 hunks)
  • rs/moq/src/ietf/publish.rs (1 hunks)
  • rs/moq/src/ietf/publish_namespace.rs (1 hunks)
  • rs/moq/src/ietf/setup.rs (1 hunks)
  • rs/moq/src/ietf/subscribe.rs (1 hunks)
  • rs/moq/src/ietf/subscribe_namespace.rs (1 hunks)
  • rs/moq/src/ietf/track.rs (1 hunks)
  • rs/moq/src/lite/mod.rs (2 hunks)
  • rs/moq/src/lite/parameters.rs (1 hunks)
  • rs/moq/src/lite/setup.rs (1 hunks)
  • rs/moq/src/session.rs (4 hunks)
💤 Files with no reviewable changes (1)
  • rs/moq/src/coding/mod.rs
🧰 Additional context used
📓 Path-based instructions (1)
rs/**/src/**/*.rs

📄 CodeRabbit inference engine (CLAUDE.md)

Write Rust tests integrated within source files (unit tests alongside code).

Files:

  • rs/moq/src/ietf/setup.rs
  • rs/moq/src/ietf/mod.rs
  • rs/moq/src/lite/parameters.rs
  • rs/moq/src/ietf/subscribe.rs
  • rs/moq/src/ietf/parameters.rs
  • rs/moq/src/ietf/publish_namespace.rs
  • rs/moq/src/lite/mod.rs
  • rs/moq/src/ietf/fetch.rs
  • rs/moq/src/ietf/subscribe_namespace.rs
  • rs/moq/src/ietf/track.rs
  • rs/moq/src/lite/setup.rs
  • rs/moq/src/session.rs
  • rs/moq/src/ietf/publish.rs
🧬 Code graph analysis (11)
rs/moq/src/ietf/setup.rs (1)
js/moq/src/ietf/parameters.ts (1)
  • Parameters (3-55)
rs/moq/src/lite/parameters.rs (1)
js/moq/src/ietf/parameters.ts (1)
  • Parameters (3-55)
rs/moq/src/ietf/subscribe.rs (1)
js/moq/src/ietf/parameters.ts (1)
  • Parameters (3-55)
rs/moq/src/ietf/parameters.rs (5)
js/moq/src/ietf/parameters.ts (1)
  • Parameters (3-55)
rs/moq/src/ietf/fetch.rs (12)
  • decode (67-100)
  • decode (125-138)
  • decode (161-174)
  • decode (193-202)
  • decode (216-219)
  • decode (237-240)
  • encode (32-63)
  • encode (116-123)
  • encode (152-159)
  • encode (187-191)
  • encode (212-214)
  • encode (231-233)
rs/moq/src/ietf/publish.rs (6)
  • decode (136-147)
  • decode (182-205)
  • decode (236-245)
  • encode (129-134)
  • encode (164-180)
  • encode (230-234)
rs/moq/src/ietf/publish_namespace.rs (10)
  • decode (30-41)
  • decode (57-60)
  • decode (80-90)
  • decode (105-108)
  • decode (128-137)
  • encode (24-28)
  • encode (53-55)
  • encode (74-78)
  • encode (101-103)
  • encode (122-126)
rs/moq/src/ietf/setup.rs (4)
  • decode (20-25)
  • decode (52-57)
  • encode (28-31)
  • encode (47-50)
rs/moq/src/ietf/publish_namespace.rs (1)
js/moq/src/ietf/parameters.ts (1)
  • Parameters (3-55)
rs/moq/src/ietf/fetch.rs (2)
rs/moq/src/ietf/namespace.rs (2)
  • decode_namespace (19-33)
  • encode_namespace (4-16)
js/moq/src/ietf/parameters.ts (1)
  • Parameters (3-55)
rs/moq/src/ietf/subscribe_namespace.rs (1)
js/moq/src/ietf/parameters.ts (1)
  • Parameters (3-55)
rs/moq/src/ietf/track.rs (1)
js/moq/src/ietf/parameters.ts (1)
  • Parameters (3-55)
rs/moq/src/lite/setup.rs (1)
js/moq/src/ietf/parameters.ts (1)
  • Parameters (3-55)
rs/moq/src/session.rs (2)
js/moq/src/ietf/parameters.ts (1)
  • Parameters (3-55)
js/moq/src/ietf/setup.ts (1)
  • ServerSetup (72-123)
rs/moq/src/ietf/publish.rs (2)
rs/moq/src/ietf/namespace.rs (2)
  • decode_namespace (19-33)
  • encode_namespace (4-16)
js/moq/src/ietf/parameters.ts (1)
  • Parameters (3-55)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Check
🔇 Additional comments (8)
rs/moq/src/ietf/mod.rs (1)

8-8: LGTM! Parameters module properly exposed.

The module declaration and public re-export follow standard Rust patterns and correctly expose the new Parameters type from the ietf module.

Also applies to: 26-26

rs/moq/src/lite/setup.rs (1)

1-4: LGTM! Import path correctly updated.

The import statement has been properly updated to reference Parameters from the lite module, aligning with the module reorganization.

rs/moq/src/ietf/track.rs (1)

9-9: LGTM! Import path correctly updated.

Parameters now correctly imported from crate::ietf, aligning with the module reorganization. The decode logic remains unchanged.

rs/moq/src/ietf/subscribe_namespace.rs (1)

5-9: LGTM! Import reorganization correctly applied.

The import statement properly references Parameters from crate::ietf, maintaining consistency with the broader module reorganization.

rs/moq/src/ietf/setup.rs (1)

1-4: LGTM! Import path correctly updated.

Parameters now properly imported from the ietf module, aligning with the refactoring to centralize parameter handling in the ietf namespace.

rs/moq/src/ietf/publish_namespace.rs (1)

5-9: LGTM! Import path correctly updated.

Parameters now imported from crate::ietf, consistent with the module reorganization across the ietf namespace.

rs/moq/src/lite/mod.rs (1)

5-5: LGTM! Parameters module properly exposed in lite namespace.

The module declaration and public re-export correctly expose the lite-specific Parameters type, following standard Rust module patterns.

Also applies to: 17-17

rs/moq/src/ietf/fetch.rs (1)

4-7: LGTM! Import reorganization correctly applied.

Parameters has been properly moved from the coding module imports to the ietf module imports. The decode logic for Fetch and FetchOk remains functionally unchanged.

@kixelated kixelated merged commit 117fa73 into main Nov 2, 2025
1 check passed
@kixelated kixelated deleted the fix-parameters branch November 2, 2025 22:09
@moq-bot moq-bot bot mentioned this pull request Nov 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants