Skip to content

irc: fix RELAYMSG nick missing required separator - #2259

Closed
johnnyxmas wants to merge 2 commits into
42wim:masterfrom
johnnyxmas:fix/relaymsg-separator-clean
Closed

johnnyxmas wants to merge 2 commits into
42wim:masterfrom
johnnyxmas:fix/relaymsg-separator-clean

Conversation

@johnnyxmas

Copy link
Copy Markdown

Summary

doSend() sanitizes the outgoing RELAYMSG nick but never appends a separator/protocol suffix (e.g. alice/discord). Servers that enforce draft/relaymsg's separator requirement (e.g. Ergo, when relaymsg.separators is configured) reject every such RELAYMSG with ERR_INVALID_NICK, so no message from any bridged platform reaches IRC when the target network enforces this — reproducible 100% of the time, regardless of which user is speaking.

Also fixes a related bug: modifyUsername() in gateway/gateway.go unconditionally applies the destination bridge's RemoteNickFormat template (e.g. "{NICK}: ") to Username before it reaches the IRC bridge. For RELAYMSG destinations this bakes stray punctuation into the nick before sanitizeNick runs (e.g. "alice: " → "alice--" after sanitizing), producing a mangled/truncated nick even once the separator is fixed. RELAYMSG doesn't need a text-prefix format at all — the nick itself is the sender identity — so this skips RemoteNickFormat templating specifically for IRC destinations with UseRelayMsg enabled, while still honoring StripNick/ReplaceNicks.

Reproduction

Reproduced against a live Ergo instance with relaymsg.separators: ["/"] configured. Every Discord/Slack → IRC message failed identically:

> RELAYMSG #channel alice-- hello
< FAIL RELAYMSG INVALID_NICK :Relayed nicknames MUST contain a relaymsg separator from this set: /

Confirmed via debug logging (DebugLevel=2) that this is what matterbridge actually sends — not a config issue on the Ergo side. IRC → other platforms, and Discord ↔ Slack, were unaffected; only the RELAYMSG-based * → IRC path was broken.

Fix

  • New relayMsgNick(nick, protocol, maxNickLen string/int) helper: sanitizes the nick, then appends /<protocol>. Truncates the base name (not the suffix) against the server's advertised NICKLEN when known, on a UTF-8 rune boundary, so long names can't silently truncate the required suffix back into the same failure.
  • gateway.modifyUsername(): skip RemoteNickFormat templating for IRC+UseRelayMsg destinations, since RELAYMSG doesn't use a text-prefix format.
  • Added unit tests for sanitizeNick/relayMsgNick covering the basic case, truncation + suffix preservation, UTF-8 rune-boundary safety, and the degenerate case where the suffix alone exceeds maxNickLen.

Test plan

  • go build ./...
  • go test ./... (full suite, no failures)
  • go vet ./bridge/irc/... ./gateway/...
  • gofmt -l clean on touched files
  • New unit tests in bridge/irc/irc_test.go pass
  • Manually verified against a live Ergo server: before the fix, 100% of Discord/Slack → IRC RELAYMSGs were rejected with INVALID_NICK; the fix produces valid nicks like alice/discord that Ergo accepts

🤖 Generated with Claude Code

…yed message to be rejected

doSend() sanitized the nick for RELAYMSG but never appended a
separator/protocol suffix (e.g. "alice/discord"). Servers that enforce
draft/relaymsg's separator requirement (e.g. Ergo with relaymsg.separators
configured) reject every such RELAYMSG with ERR_INVALID_NICK, so no message
from any bridged platform ever reaches IRC when relaymsg.separators is set -
this reproduces 100% regardless of which user is speaking.

Also fixes a related issue: modifyUsername() in gateway.go unconditionally
applies the destination's RemoteNickFormat template (e.g. "{NICK}: ") to
Username before it reaches the IRC bridge. For RELAYMSG destinations this
punctuation gets baked into the nick before sanitizeNick runs, producing
mangled/truncated nicks (e.g. "alice: " -> "alice--" after sanitizing).
RELAYMSG doesn't need a text-prefix format at all - the nick itself is the
sender identity - so skip RemoteNickFormat templating for IRC+UseRelayMsg
destinations while still honoring StripNick/ReplaceNicks.

Reproduced against a live Ergo instance with relaymsg.separators=["/"]:
every Discord/Slack -> IRC message failed with
"FAIL RELAYMSG INVALID_NICK :Relayed nicknames MUST contain a relaymsg
separator from this set: /" until this fix.
Same lint cleanup as applied on the fork's master - no functional changes.
Verified with golangci-lint v2.12.2 locally (0 issues).
@johnnyxmas

Copy link
Copy Markdown
Author

This fix already landed on master via 3f7533c / 02daefd (irc: fix RELAYMSG nick missing required separator + lint follow-up). Closing as redundant.

@johnnyxmas

Copy link
Copy Markdown
Author

Correction: my previous close comment was based on comparing against my own fork's master, not this repo's master — the fix has NOT actually landed upstream. Reopening; this PR is still valid and needed.

@johnnyxmas

Copy link
Copy Markdown
Author

Maintainer has been inactive on this repo since August 2024 (over two years), so I'm maintaining these fixes on my own fork (johnnyxmas/matterbridge) instead of waiting on upstream review. Closing this PR.

@johnnyxmas johnnyxmas closed this Sep 2, 2026
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