From 2f9234318cc3fea33149f91c4fcaa60c616ab192 Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Sun, 17 May 2020 14:02:59 -0400 Subject: [PATCH] fix #1021 --- irc/channel.go | 10 ++++++---- irc/modes.go | 17 +++++++++++++++-- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/irc/channel.go b/irc/channel.go index 8c689744..d57fce15 100644 --- a/irc/channel.go +++ b/irc/channel.go @@ -564,7 +564,12 @@ func (channel *Channel) hasClient(client *Client) bool { // func (channel *Channel) modeStrings(client *Client) (result []string) { - isMember := client.HasMode(modes.Operator) || channel.hasClient(client) + hasPrivs := client.HasMode(modes.Operator) + + channel.stateMutex.RLock() + defer channel.stateMutex.RUnlock() + + isMember := hasPrivs || channel.members[client] != nil showKey := isMember && (channel.key != "") showUserLimit := channel.userLimit > 0 @@ -580,9 +585,6 @@ func (channel *Channel) modeStrings(client *Client) (result []string) { mods += channel.flags.String() - channel.stateMutex.RLock() - defer channel.stateMutex.RUnlock() - result = []string{mods} // args for flags with args: The order must match above to keep diff --git a/irc/modes.go b/irc/modes.go index bfbfc271..11912544 100644 --- a/irc/modes.go +++ b/irc/modes.go @@ -134,6 +134,15 @@ func ParseDefaultUserModes(rawModes *string) modes.ModeChanges { return modeChanges } +// #1021: channel key must be valid as a non-final parameter +func validateChannelKey(key string) bool { + // empty string is valid in this context because it unsets the mode + if len(key) == 0 { + return true + } + return key[0] != ':' && strings.IndexByte(key, ' ') == -1 +} + // ApplyChannelModeChanges applies a given set of mode changes. func (channel *Channel) ApplyChannelModeChanges(client *Client, isSamode bool, changes modes.ModeChanges, rb *ResponseBuffer) (applied modes.ModeChanges) { // so we only output one warning for each list type when full @@ -244,8 +253,12 @@ func (channel *Channel) ApplyChannelModeChanges(client *Client, isSamode bool, c case modes.Key: switch change.Op { case modes.Add: - channel.setKey(change.Arg) - applied = append(applied, change) + if validateChannelKey(change.Arg) { + channel.setKey(change.Arg) + applied = append(applied, change) + } else { + rb.Add(nil, client.server.name, ERR_INVALIDMODEPARAM, details.nick, "*", fmt.Sprintf(client.t("Invalid mode %[1]s parameter: %[2]s"), string(change.Mode), change.Arg)) + } case modes.Remove: channel.setKey("") applied = append(applied, change)