Explorar el Código

review fix: add maxParams for service commands

tags/v1.0.0-rc1
Shivaram Lingamneni hace 5 años
padre
commit
598d9a025b
Se han modificado 4 ficheros con 85 adiciones y 12 borrados
  1. 1
    2
      irc/chanserv.go
  2. 2
    2
      irc/hostserv.go
  3. 30
    8
      irc/services.go
  4. 52
    0
      irc/utils/fieldsn.go

+ 1
- 2
irc/chanserv.go Ver fichero

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

+ 2
- 2
irc/hostserv.go Ver fichero

@@ -7,7 +7,6 @@ import (
7 7
 	"errors"
8 8
 	"fmt"
9 9
 	"regexp"
10
-	"strings"
11 10
 	"time"
12 11
 )
13 12
 
@@ -125,6 +124,7 @@ for the rejection.`,
125 124
 			capabs:    []string{"vhosts"},
126 125
 			enabled:   hostservEnabled,
127 126
 			minParams: 1,
127
+			maxParams: 2,
128 128
 		},
129 129
 	}
130 130
 )
@@ -296,7 +296,7 @@ func hsRejectHandler(server *Server, client *Client, command string, params []st
296 296
 	var reason string
297 297
 	user := params[0]
298 298
 	if len(params) > 1 {
299
-		reason = strings.Join(params[1:], " ")
299
+		reason = params[1]
300 300
 	}
301 301
 
302 302
 	vhostInfo, err := server.accounts.VHostReject(user, reason)

+ 30
- 8
irc/services.go Ver fichero

@@ -11,6 +11,7 @@ import (
11 11
 
12 12
 	"github.com/goshuirc/irc-go/ircfmt"
13 13
 	"github.com/goshuirc/irc-go/ircmsg"
14
+	"github.com/oragono/oragono/irc/utils"
14 15
 )
15 16
 
16 17
 // defines an IRC service, e.g., NICKSERV
@@ -32,6 +33,7 @@ type serviceCommand struct {
32 33
 	authRequired bool
33 34
 	enabled      func(*Config) bool // is this command enabled in the server config?
34 35
 	minParams    int
36
+	maxParams    int // split into at most n params, with last param containing remaining unsplit text
35 37
 }
36 38
 
37 39
 // 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
97 99
 		return false
98 100
 	}
99 101
 
100
-	serviceRunCommand(service, server, client, msg.Params, rb)
102
+	if len(msg.Params) == 0 {
103
+		return false
104
+	}
105
+	commandName := strings.ToLower(msg.Params[0])
106
+	params := msg.Params[1:]
107
+	cmd := lookupServiceCommand(service.Commands, commandName)
108
+	// for a maxParams command, join all final parameters together if necessary
109
+	if cmd != nil && cmd.maxParams != 0 && cmd.maxParams < len(params) {
110
+		newParams := make([]string, cmd.maxParams)
111
+		copy(newParams, params[:cmd.maxParams-1])
112
+		newParams[cmd.maxParams-1] = strings.Join(params[cmd.maxParams-1:], " ")
113
+		params = newParams
114
+	}
115
+	serviceRunCommand(service, server, client, cmd, commandName, params, rb)
101 116
 	return false
102 117
 }
103 118
 
104 119
 // generic handler for service PRIVMSG, like `/msg NickServ INFO`
105 120
 func servicePrivmsgHandler(service *ircService, server *Server, client *Client, message string, rb *ResponseBuffer) {
106
-	serviceRunCommand(service, server, client, strings.Fields(message), rb)
107
-}
108
-
109
-// actually execute a service command
110
-func serviceRunCommand(service *ircService, server *Server, client *Client, params []string, rb *ResponseBuffer) {
121
+	params := strings.Fields(message)
111 122
 	if len(params) == 0 {
112 123
 		return
113 124
 	}
125
+
126
+	// look up the service command to see how to parse it
114 127
 	commandName := strings.ToLower(params[0])
115
-	params = params[1:]
128
+	cmd := lookupServiceCommand(service.Commands, commandName)
129
+	// reparse if needed
130
+	if cmd != nil && cmd.maxParams != 0 {
131
+		params = utils.FieldsN(message, cmd.maxParams+1)[1:]
132
+	} else {
133
+		params = params[1:]
134
+	}
135
+	serviceRunCommand(service, server, client, cmd, commandName, params, rb)
136
+}
116 137
 
138
+// actually execute a service command
139
+func serviceRunCommand(service *ircService, server *Server, client *Client, cmd *serviceCommand, commandName string, params []string, rb *ResponseBuffer) {
117 140
 	nick := rb.target.Nick()
118 141
 	sendNotice := func(notice string) {
119 142
 		rb.Add(nil, service.Name, "NOTICE", nick, notice)
120 143
 	}
121 144
 
122
-	cmd := lookupServiceCommand(service.Commands, commandName)
123 145
 	if cmd == nil {
124 146
 		sendNotice(fmt.Sprintf("%s /%s HELP", client.t("Unknown command. To see available commands, run"), service.ShortName))
125 147
 		return

+ 52
- 0
irc/utils/fieldsn.go Ver fichero

@@ -0,0 +1,52 @@
1
+package utils
2
+
3
+// Copyright (c) 2014 Kevin Wallace <kevin@pentabarf.net>
4
+// Found here: https://github.com/kevinwallace/fieldsn
5
+// Released under the MIT license
6
+// XXX this implementation treats negative n as "return nil",
7
+// unlike stdlib SplitN and friends, which treat it as "no limit"
8
+
9
+// Original source code below:
10
+
11
+// Package fieldsn implements FieldsN and FieldsFuncN,
12
+// which are conspicuously missing from the strings package.
13
+
14
+import (
15
+	"unicode"
16
+)
17
+
18
+// FieldsN is like strings.Fields, but returns at most n fields,
19
+// and the nth field includes any whitespace at the end of the string.
20
+func FieldsN(s string, n int) []string {
21
+	return FieldsFuncN(s, unicode.IsSpace, n)
22
+}
23
+
24
+// FieldsFuncN is like strings.FieldsFunc, but returns at most n fields,
25
+// and the nth field includes any runes at the end of the string normally excluded by f.
26
+func FieldsFuncN(s string, f func(rune) bool, n int) []string {
27
+	if n <= 0 {
28
+		return nil
29
+	}
30
+
31
+	a := make([]string, 0, n)
32
+	na := 0
33
+	fieldStart := -1
34
+	for i, rune := range s {
35
+		if f(rune) {
36
+			if fieldStart >= 0 {
37
+				a = append(a, s[fieldStart:i])
38
+				na++
39
+				fieldStart = -1
40
+			}
41
+		} else if fieldStart == -1 {
42
+			fieldStart = i
43
+			if na+1 == n {
44
+				break
45
+			}
46
+		}
47
+	}
48
+	if fieldStart >= 0 {
49
+		a = append(a, s[fieldStart:])
50
+	}
51
+	return a
52
+}

Loading…
Cancelar
Guardar