Skip to content

fix(cli): canonicalize the channel id channel and message queries filter on - #6877

Open
Chessing234 wants to merge 1 commit into
block:mainfrom
Chessing234:cli-canonical-channel-uuid
Open

fix(cli): canonicalize the channel id channel and message queries filter on#6877
Chessing234 wants to merge 1 commit into
block:mainfrom
Chessing234:cli-canonical-channel-uuid

Conversation

@Chessing234

Copy link
Copy Markdown
Contributor

Found by reading validate_uuid against its callers; no issue filed.

validate_uuid checks that its argument parses and discards the result. Uuid::parse_str is deliberately lenient — it accepts uppercase, the unhyphenated 32-character form, braces, and a urn:uuid: prefix — so all four spellings pass and then reach a filter unchanged:

validate_uuid(channel_id)?;
let filter = serde_json::json!({ "kinds": [9, ...], "#h": [channel_id], "limit": limit });

Every h and d tag in the tree is written in the canonical lowercase hyphenated form, and a NIP-01 generic tag filter compares tag values byte for byte (filter_match_one). So a non-canonical spelling matches nothing, and the command reports that as no results rather than as bad input:

$ buzz channels get --channel 550E8400-E29B-41D4-A716-446655440000
null
$ buzz messages list --channel {550e8400-e29b-41d4-a716-446655440000}
[]

Five commands are affected: channels get, channels members, channels canvas, messages list, messages thread.

What is not affected

The send path is fine, and it's worth saying why. cmd_send_message does parse_uuid(&p.channel_id)? and hands the typed Uuid to the SDK builders, which write the canonical form — so a message sent with a non-canonical --channel still lands with a correct h tag. Nothing is published wrong by this bug.

The one place it leaks into a send is the mention preflight: resolve_content_mentions receives the raw argument and filters {"kinds":[39002], "#d":[channel_id]} on it, so with an @ in the content the send fails with

could not load channel membership for mention preflight

which is a confusing way to say "your channel id isn't in the form the relay stores".

The change

Parse once, filter on the canonical form. messages thread is the clearest case — it already had let expected_channel_id = parse_uuid(channel_id)? on the line above and was still building both filters from the raw argument.

Two unit tests in validate.rs carry the reasoning: one asserts that validate_uuid really does pass all four non-canonical spellings (so it fails loudly if the leniency ever changes and this canonicalization becomes unnecessary), and one asserts that parse_uuid(...).hyphenated().to_string() collapses every spelling onto the single form the relay stores.

Related

Same root cause as, but independent of, #5966 / #5970 / #5984, which fix the hex-id half of this (validate_hex64 documented as lowercase, implemented with is_ascii_hexdigit). This is the UUID half. The same gap remains in workflows, repos and projects; those are separate diffs.

Testing

  • cargo test -p buzz-cli --lib — 365 passed, 0 failed
  • cargo clippy -p buzz-cli --all-targets — clean
  • cargo fmt --all -- --check — clean

I have not exercised these commands against a live relay; the claim about byte-for-byte tag matching is read from filter_match_one and from the fact that nothing in the relay's ingest path canonicalizes an h/d tag before storing it.

…ter on

validate_uuid checks that the argument parses and throws the result away.
Uuid::parse_str accepts uppercase, the unhyphenated 32-character form,
braces and a urn:uuid: prefix, so all four reach the filter unchanged.

Every h and d tag in the tree is written in the canonical lowercase
hyphenated form, and a NIP-01 generic tag filter compares tag values byte
for byte. A non-canonical spelling therefore matches nothing, and each of
these commands prints an empty result rather than an error:

  channels get, channels members, channels canvas, messages list,
  messages thread

The send path is unaffected: it parses the argument into a Uuid and hands
that to the SDK builders, which write the canonical form. The one place
that leaked into a send is the mention preflight, which filtered on the
raw string and so failed with "could not load channel membership" instead
of the parse error the input deserves.

Parse once and filter on the canonical form. messages thread already had
the parsed value to hand and was still building its filters from the raw
argument.

Signed-off-by: Taksh <takshkothari09@gmail.com>
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.

1 participant