Allow channel sender names of up to 31 characters
The firmware keeps a node name in 32 bytes, but the sender prefix and the @[Name] mention matched only 20 characters. A longer name stayed in the body: the transcript showed no sender for it, and its reactions showed as new messages. Found on hardware with "Hazelwood r0b3.Anduril" (22 characters). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
a323342971
commit
f3aa8e5aef
2 files changed
+24
-5
No files matched your search
@@ -35,17 +35,21 @@ from urllib.parse import parse_qs, quote, urlsplit
|
||||
# not one time for each candidate channel. Thus the reception path pays almost nothing.
|
||||
|
||||
#: Matches the ``Name: message`` convention that channel senders use to identify themselves
|
||||
#: (the protocol has no sender field). The name is 1–20 characters that are not colons, and
|
||||
#: (the protocol has no sender field). The name is 1–31 characters that are not colons, and
|
||||
#: ``": "`` must follow it. This rule is strict enough that it does not match ``http://…``
|
||||
#: or ``note:x``.
|
||||
SENDER_PREFIX = re.compile(r"^([^\s:][^:]{0,19}):[ \t]+(.*)$", re.DOTALL)
|
||||
#: or ``note:x``. The firmware keeps a node name in 32 bytes with its terminator, so 31 is
|
||||
#: the longest name that a sender can have. A limit of 20 left
|
||||
#: a longer name in the body. Then the transcript showed no sender for it, and a reaction
|
||||
#: from it did not read as a reaction.
|
||||
SENDER_PREFIX = re.compile(r"^([^\s:][^:]{0,30}):[ \t]+(.*)$", re.DOTALL)
|
||||
|
||||
#: Matches an ``@[Name]`` mention token, which the reply flow puts into the compose line in
|
||||
#: advance. A transcript renders each token as a bare ``@Name`` in the hue of that sender,
|
||||
#: and does not show the brackets. The history face of the CLI also takes out the same
|
||||
#: names. Thus the token is defined here, with the remainder of the message-body parsing, and
|
||||
#: not in one of the two renderers. The name is 1–20 characters that are not ``]``.
|
||||
MENTION = re.compile(r"@\[([^\]]{1,20})\]")
|
||||
#: not in one of the two renderers. The name is 1–31 characters that are not ``]``, the
|
||||
#: same limit as :data:`SENDER_PREFIX`.
|
||||
MENTION = re.compile(r"@\[([^\]]{1,31})\]")
|
||||
|
||||
|
||||
def split_channel_sender(text: str) -> tuple[str | None, str]:
|
||||
|
||||
@@ -393,3 +393,18 @@ def test_the_messages_list_previews_a_reaction_in_words() -> None:
|
||||
assert "Bob" in preview and "reacted 👍" in preview and "@[" not in preview
|
||||
ours = ChatMessage(text=reactions.direct_text("😂", "hi", _T), outbound=True)
|
||||
assert "reacted 😂" in _preview_text(ours, lambda name: None).plain
|
||||
|
||||
|
||||
def test_a_reaction_from_a_node_with_a_long_name_folds() -> None:
|
||||
"""A node name can have 31 characters. A sender of 22 is still split off its reaction.
|
||||
|
||||
The two messages are from the hardware log that found the fault: the name limit was 20,
|
||||
so the reaction of ``Hazelwood r0b3.Anduril`` showed as a new message.
|
||||
"""
|
||||
fold = ReactionFold(channel=True)
|
||||
target = _channel("Hazelwood: ⚽ Union 2-1 at Chicago Fire (59')", 1_792_029_645)
|
||||
fold.take(target)
|
||||
react = _channel("Hazelwood r0b3.Anduril: @[Hazelwood]🔥\nmzjsjjpk", 1_792_029_654)
|
||||
assert fold.take(react) is True
|
||||
(badge,) = fold.badges(target)
|
||||
assert badge.emoji == "🔥" and badge.reactors == [reactions.Reactor("Hazelwood r0b3.Anduril")]
|
||||
Reference in new issue
Block a user