Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion sopel/irc/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,11 @@ def safe_text_length(self, recipient: str) -> int:
and can be used with :func:`sopel.tools.get_sendable_message`.

"""
# Clients "SHOULD" assume messages will be truncated at 512 bytes if
# the LINELEN ISUPPORT token is not present.
# See https://modern.ircdocs.horse/#linelen-parameter
max_line_length = self.isupport.get('LINELEN', 512)

if self.hostmask is not None:
hostmask_length = len(self.hostmask)
else:
Expand All @@ -200,7 +205,7 @@ def safe_text_length(self, recipient: str) -> int:
)

return (
512 # maximum IRC line length in bytes, per RFC
max_line_length
- 1 # leading colon
- hostmask_length # calculated/maximum length of own hostmask prefix
- 1 # space between prefix & command
Expand Down
1 change: 1 addition & 0 deletions sopel/irc/isupport.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ def _parse_prefix(value):
'HOSTLEN': int,
'INVEX': _optional(_single_character, default='I'),
'KICKLEN': int,
'LINELEN': int,
'MAXLIST': _map_items(int),
'MAXTARGETS': _optional(int),
'MODES': _optional(int),
Expand Down
13 changes: 13 additions & 0 deletions test/test_irc.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,19 @@ def prefix_length(bot):
return 1 + len(bot.nick) + 1 + 1 + len(bot.user) + 1 + 63 + 1


def test_safe_text_length_with_linelen_no_hostmask(tmpconfig, botfactory):
# this test doesn't work using only the plain `bot` fixture
bot = botfactory.preloaded(tmpconfig)

assert bot.hostmask is None
bot.on_message(
':irc.example.com 005 Sopel NETWORK=LLTest LINELEN=1024 '
':are supported by this server')
# normal lines are capped at 512 bytes, and 1024 is exactly twice that
# expect the extra 512 in full + the result of hostmask_unknown below
assert bot.safe_text_length('#channel') == 414 + 512


def test_safe_text_length_hostmask_unknown(bot):
assert bot.hostmask is None
assert bot.safe_text_length('#channel') == 414
Expand Down