skip empty tags, allow = in tag values, better clarify ; split, add IRCv3 tag parsing comment to ParseLine()

This commit is contained in:
Jake Bailey 2016-01-12 20:00:40 -06:00
parent 73f523f252
commit 20ef362b1d
2 changed files with 33 additions and 8 deletions

View File

@ -105,6 +105,9 @@ func (line *Line) Public() bool {
// CTCP command separated from any subsequent text. Then, CTCP ACTIONs are // CTCP command separated from any subsequent text. Then, CTCP ACTIONs are
// rewritten such that Line.Cmd == ACTION. Other CTCP messages have Cmd // rewritten such that Line.Cmd == ACTION. Other CTCP messages have Cmd
// set to CTCP or CTCPREPLY, and the CTCP command prepended to line.Args. // set to CTCP or CTCPREPLY, and the CTCP command prepended to line.Args.
//
// ParseLine also parses IRCv3 tags, if received. If a line does not have
// the tags section, Line.Tags will be nil.
func ParseLine(s string) *Line { func ParseLine(s string) *Line {
line := &Line{Raw: s} line := &Line{Raw: s}
@ -117,19 +120,17 @@ func ParseLine(s string) *Line {
return nil return nil
} }
// all tags are escaped, so splitting on ; is right by design // ; is represented as \: in a tag, so it's safe to split on ;
for _, tag := range strings.Split(rawTags, ";") { for _, tag := range strings.Split(rawTags, ";") {
if tag == "" { if tag == "" {
return nil continue
} }
pair := strings.Split(tagsReplacer.Replace(tag), "=") pair := strings.SplitN(tagsReplacer.Replace(tag), "=", 2)
if len(pair) < 2 { if len(pair) < 2 {
line.Tags[tag] = "" line.Tags[tag] = ""
} else if len(pair) == 2 {
line.Tags[pair[0]] = pair[1]
} else { } else {
return nil line.Tags[pair[0]] = pair[1]
} }
} }
} }

View File

@ -137,8 +137,32 @@ func TestLineTags(t *testing.T) {
Args: []string{"me", "Hello"}, Args: []string{"me", "Hello"},
}, },
}, },
{"@a=a; :nick!ident@host.com PRIVMSG me :Hello", nil}, // Bad inputs { // Skip empty tag
{"@a=a=a :nick!ident@host.com PRIVMSG me :Hello", nil}, "@a=a; :nick!ident@host.com PRIVMSG me :Hello",
&Line{
Tags: map[string]string{"a": "a"},
Nick: "nick",
Ident: "ident",
Host: "host.com",
Src: "nick!ident@host.com",
Cmd: PRIVMSG,
Raw: "@a=a; :nick!ident@host.com PRIVMSG me :Hello",
Args: []string{"me", "Hello"},
},
},
{ // = in tag
"@a=a=a; :nick!ident@host.com PRIVMSG me :Hello",
&Line{
Tags: map[string]string{"a": "a=a"},
Nick: "nick",
Ident: "ident",
Host: "host.com",
Src: "nick!ident@host.com",
Cmd: PRIVMSG,
Raw: "@a=a=a; :nick!ident@host.com PRIVMSG me :Hello",
Args: []string{"me", "Hello"},
},
},
} }
for i, test := range tests { for i, test := range tests {