ForcePilot/backend/package/yuxi/channels/adapters/irc/sanitize.py

54 lines
1.3 KiB
Python
Raw Normal View History

from __future__ import annotations
import re
_IRC_CONTROL_START = 0x00
_IRC_CONTROL_END = 0x1F
_IRC_DEL = 0x7F
_LITERAL_ESCAPE_PATTERN = re.compile(r"\\x[0-9a-fA-F]{2}")
def is_irc_control_char(ch: str) -> bool:
if len(ch) != 1:
return False
cp = ord(ch)
return cp < 0x20 or cp == 0x7F
def has_irc_control_chars(text: str) -> bool:
return any(is_irc_control_char(c) for c in text)
def strip_irc_control_chars(text: str) -> str:
return "".join(c for c in text if not is_irc_control_char(c))
def decode_literal_escapes(text: str) -> str:
"""Strip literal escape sequences (\\xNN) from inbound text.
Prevents attackers from injecting IRC control characters via literal
backslash-x escape representations (e.g. \\x01 for CTCP delimiter).
"""
return _LITERAL_ESCAPE_PATTERN.sub("", text)
def has_literal_escapes(text: str) -> bool:
return bool(_LITERAL_ESCAPE_PATTERN.search(text))
def sanitize_outbound_text(text: str) -> str:
text = text.replace("\n", " ").replace("\r", " ")
return strip_irc_control_chars(text)
def sanitize_inbound_text(text: str) -> str:
text = decode_literal_escapes(text)
return strip_irc_control_chars(text)
def sanitize_irc_target(target: str) -> str:
cleaned = strip_irc_control_chars(target)
cleaned = cleaned.replace(" ", "_")
return cleaned