3
0
mirror of https://github.com/ergochat/ergo.git synced 2024-11-10 22:19:31 +01:00

review fix: add maxParams for service commands

This commit is contained in:
Shivaram Lingamneni 2019-01-04 10:03:12 -05:00
parent 4caa362f18
commit 598d9a025b
4 changed files with 86 additions and 13 deletions

View File

@ -91,7 +91,6 @@ func csNotice(rb *ResponseBuffer, text string) {
func csAmodeHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
channelName := params[0]
modeChange := strings.Join(params[1:], " ")
channel := server.channels.Get(channelName)
if channel == nil {
@ -102,7 +101,7 @@ func csAmodeHandler(server *Server, client *Client, command string, params []str
return
}
modeChanges, unknown := modes.ParseChannelModeChanges(strings.Fields(modeChange)...)
modeChanges, unknown := modes.ParseChannelModeChanges(params[1:]...)
var change modes.ModeChange
if len(modeChanges) > 1 || len(unknown) > 0 {
csNotice(rb, client.t("Invalid mode change"))

View File

@ -7,7 +7,6 @@ import (
"errors"
"fmt"
"regexp"
"strings"
"time"
)
@ -125,6 +124,7 @@ for the rejection.`,
capabs: []string{"vhosts"},
enabled: hostservEnabled,
minParams: 1,
maxParams: 2,
},
}
)
@ -296,7 +296,7 @@ func hsRejectHandler(server *Server, client *Client, command string, params []st
var reason string
user := params[0]
if len(params) > 1 {
reason = strings.Join(params[1:], " ")
reason = params[1]
}
vhostInfo, err := server.accounts.VHostReject(user, reason)

View File

@ -11,6 +11,7 @@ import (
"github.com/goshuirc/irc-go/ircfmt"
"github.com/goshuirc/irc-go/ircmsg"
"github.com/oragono/oragono/irc/utils"
)
// defines an IRC service, e.g., NICKSERV
@ -32,6 +33,7 @@ type serviceCommand struct {
authRequired bool
enabled func(*Config) bool // is this command enabled in the server config?
minParams int
maxParams int // split into at most n params, with last param containing remaining unsplit text
}
// looks up a command in the table of command definitions for a service, resolving aliases
@ -97,29 +99,49 @@ func serviceCmdHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb
return false
}
serviceRunCommand(service, server, client, msg.Params, rb)
if len(msg.Params) == 0 {
return false
}
commandName := strings.ToLower(msg.Params[0])
params := msg.Params[1:]
cmd := lookupServiceCommand(service.Commands, commandName)
// for a maxParams command, join all final parameters together if necessary
if cmd != nil && cmd.maxParams != 0 && cmd.maxParams < len(params) {
newParams := make([]string, cmd.maxParams)
copy(newParams, params[:cmd.maxParams-1])
newParams[cmd.maxParams-1] = strings.Join(params[cmd.maxParams-1:], " ")
params = newParams
}
serviceRunCommand(service, server, client, cmd, commandName, params, rb)
return false
}
// generic handler for service PRIVMSG, like `/msg NickServ INFO`
func servicePrivmsgHandler(service *ircService, server *Server, client *Client, message string, rb *ResponseBuffer) {
serviceRunCommand(service, server, client, strings.Fields(message), rb)
}
// actually execute a service command
func serviceRunCommand(service *ircService, server *Server, client *Client, params []string, rb *ResponseBuffer) {
params := strings.Fields(message)
if len(params) == 0 {
return
}
commandName := strings.ToLower(params[0])
params = params[1:]
// look up the service command to see how to parse it
commandName := strings.ToLower(params[0])
cmd := lookupServiceCommand(service.Commands, commandName)
// reparse if needed
if cmd != nil && cmd.maxParams != 0 {
params = utils.FieldsN(message, cmd.maxParams+1)[1:]
} else {
params = params[1:]
}
serviceRunCommand(service, server, client, cmd, commandName, params, rb)
}
// actually execute a service command
func serviceRunCommand(service *ircService, server *Server, client *Client, cmd *serviceCommand, commandName string, params []string, rb *ResponseBuffer) {
nick := rb.target.Nick()
sendNotice := func(notice string) {
rb.Add(nil, service.Name, "NOTICE", nick, notice)
}
cmd := lookupServiceCommand(service.Commands, commandName)
if cmd == nil {
sendNotice(fmt.Sprintf("%s /%s HELP", client.t("Unknown command. To see available commands, run"), service.ShortName))
return

52
irc/utils/fieldsn.go Normal file
View File

@ -0,0 +1,52 @@
package utils
// Copyright (c) 2014 Kevin Wallace <kevin@pentabarf.net>
// Found here: https://github.com/kevinwallace/fieldsn
// Released under the MIT license
// XXX this implementation treats negative n as "return nil",
// unlike stdlib SplitN and friends, which treat it as "no limit"
// Original source code below:
// Package fieldsn implements FieldsN and FieldsFuncN,
// which are conspicuously missing from the strings package.
import (
"unicode"
)
// FieldsN is like strings.Fields, but returns at most n fields,
// and the nth field includes any whitespace at the end of the string.
func FieldsN(s string, n int) []string {
return FieldsFuncN(s, unicode.IsSpace, n)
}
// FieldsFuncN is like strings.FieldsFunc, but returns at most n fields,
// and the nth field includes any runes at the end of the string normally excluded by f.
func FieldsFuncN(s string, f func(rune) bool, n int) []string {
if n <= 0 {
return nil
}
a := make([]string, 0, n)
na := 0
fieldStart := -1
for i, rune := range s {
if f(rune) {
if fieldStart >= 0 {
a = append(a, s[fieldStart:i])
na++
fieldStart = -1
}
} else if fieldStart == -1 {
fieldStart = i
if na+1 == n {
break
}
}
}
if fieldStart >= 0 {
a = append(a, s[fieldStart:])
}
return a
}