diff --git a/irc/handlers.go b/irc/handlers.go index 47f16652..b45cd80e 100644 --- a/irc/handlers.go +++ b/irc/handlers.go @@ -1273,11 +1273,14 @@ func sajoinHandler(server *Server, client *Client, msg ircmsg.Message, rb *Respo } // KICK {,} {,} [] +// RFC 2812 requires the number of channels to be either 1 or equal to +// the number of users. +// Addditionally, we support multiple channels and a single user. func kickHandler(server *Server, client *Client, msg ircmsg.Message, rb *ResponseBuffer) bool { hasPrivs := client.HasRoleCapabs("samode") channels := strings.Split(msg.Params[0], ",") users := strings.Split(msg.Params[1], ",") - if (len(channels) != len(users)) && (len(users) != 1) { + if (len(channels) != len(users)) && (len(users) != 1) && (len(channels) != 1) { rb.Add(nil, server.name, ERR_NEEDMOREPARAMS, client.nick, "KICK", client.t("Not enough parameters")) return false } @@ -1286,15 +1289,30 @@ func kickHandler(server *Server, client *Client, msg ircmsg.Message, rb *Respons channel string nick string } - kicks := make([]kickCmd, 0, len(channels)) - for index, channel := range channels { - if channel == "" { - continue // #679 + var kicks []kickCmd + if len(users) == 1 { + kicks = make([]kickCmd, 0, len(channels)) + // Single user, possibly multiple channels + user := users[0] + for _, channel := range channels { + if channel == "" { + continue // #679 + } + kicks = append(kicks, kickCmd{channel, user}) } - if len(users) == 1 { - kicks = append(kicks, kickCmd{channel, users[0]}) - } else { - kicks = append(kicks, kickCmd{channel, users[index]}) + } else { + // Multiple users, either a single channel or as many channels + // as users. + kicks = make([]kickCmd, 0, len(users)) + channel := channels[0] + for index, user := range users { + if len(channels) > 1 { + channel = channels[index] + } + if channel == "" { + continue // #679 + } + kicks = append(kicks, kickCmd{channel, user}) } }