Fix IRC listener relay of bodies and modes, and JOIN names (closes #127)
check / check (push) Canceled after 0s
check / check (push) Canceled after 0s
The IRC listener relayed only the first line of a PRIVMSG or NOTICE body; it now sends one line per body line. A relayed MODE change now carries its key, limit or mask, each value its own parameter, also in the echo to the user who made it. CR, LF and NUL are removed from each parameter and from each whole line sent to an IRC listener connection, so no stored value can start a line of its own. The channel name check moved into service.JoinChannel, so the IRC listener's JOIN refuses the same names with 403. Model: opus-5-5
This commit is contained in:
+28
-12
@@ -3,6 +3,7 @@ package ircserver
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"slices"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -105,7 +106,7 @@ func (c *Conn) deliverIRCMessage(
|
||||
case isNumeric(command):
|
||||
c.deliverNumeric(msg, text)
|
||||
case command == irc.CmdPrivmsg || command == irc.CmdNotice:
|
||||
c.deliverTextMessage(msg, command, text)
|
||||
c.deliverTextMessage(msg, command, bodyLines)
|
||||
case command == irc.CmdJoin:
|
||||
c.deliverJoin(msg)
|
||||
case command == irc.CmdPart:
|
||||
@@ -123,7 +124,7 @@ func (c *Conn) deliverIRCMessage(
|
||||
case command == irc.CmdWallops:
|
||||
c.deliverWallops(msg, text)
|
||||
case command == irc.CmdMode:
|
||||
c.deliverMode(msg, text)
|
||||
c.deliverMode(msg, bodyLines)
|
||||
case command == irc.CmdPing:
|
||||
// Server-originated PING — reply with PONG.
|
||||
c.sendFromServer("PING", c.serverSfx)
|
||||
@@ -179,10 +180,12 @@ func (c *Conn) deliverNumeric(
|
||||
c.send(FormatMessage(from, msg.Command, allParams...))
|
||||
}
|
||||
|
||||
// deliverTextMessage sends PRIVMSG or NOTICE.
|
||||
// deliverTextMessage sends PRIVMSG or NOTICE, one line for
|
||||
// each line of the body.
|
||||
func (c *Conn) deliverTextMessage(
|
||||
msg *db.IRCMessage,
|
||||
command, text string,
|
||||
command string,
|
||||
bodyLines []string,
|
||||
) {
|
||||
from := msg.From
|
||||
target := msg.To
|
||||
@@ -201,7 +204,9 @@ func (c *Conn) deliverTextMessage(
|
||||
prefix = from + "!" + from + "@*"
|
||||
}
|
||||
|
||||
c.send(FormatMessage(prefix, command, target, text))
|
||||
for _, line := range bodyLines {
|
||||
c.send(FormatMessage(prefix, command, target, line))
|
||||
}
|
||||
}
|
||||
|
||||
// deliverJoin sends a JOIN notification.
|
||||
@@ -351,15 +356,26 @@ func (c *Conn) deliverWallops(
|
||||
))
|
||||
}
|
||||
|
||||
// deliverMode sends a MODE change notification.
|
||||
// deliverMode sends a MODE change notification. The first
|
||||
// body line is the change, possibly followed by its values
|
||||
// separated by spaces ("+o bob"); any further lines are
|
||||
// values ("+k", "secret"). Each goes out as its own
|
||||
// parameter, as IRC sends them.
|
||||
func (c *Conn) deliverMode(
|
||||
msg *db.IRCMessage,
|
||||
text string,
|
||||
bodyLines []string,
|
||||
) {
|
||||
prefix := msg.From + "!" + msg.From + "@*"
|
||||
target := msg.To
|
||||
|
||||
if text != "" {
|
||||
c.send(FormatMessage(prefix, "MODE", target, text))
|
||||
if len(bodyLines) == 0 || bodyLines[0] == "" {
|
||||
return
|
||||
}
|
||||
|
||||
prefix := msg.From + "!" + msg.From + "@*"
|
||||
|
||||
params := slices.Concat(
|
||||
[]string{msg.To},
|
||||
strings.Fields(bodyLines[0]),
|
||||
bodyLines[1:],
|
||||
)
|
||||
|
||||
c.send(FormatMessage(prefix, "MODE", params...))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user