mirror of https://github.com/fluffle/goirc
handlers: check array bounds before indexing
This commit is contained in:
parent
1e190eb233
commit
f0ae9bb509
|
@ -73,6 +73,9 @@ func (conn *Conn) h_433(line *Line) {
|
||||||
me := conn.Me()
|
me := conn.Me()
|
||||||
neu := conn.cfg.NewNick(line.Args[1])
|
neu := conn.cfg.NewNick(line.Args[1])
|
||||||
conn.Nick(neu)
|
conn.Nick(neu)
|
||||||
|
if !line.argslen(1) {
|
||||||
|
return
|
||||||
|
}
|
||||||
// if this is happening before we're properly connected (i.e. the nick
|
// if this is happening before we're properly connected (i.e. the nick
|
||||||
// we sent in the initial NICK command is in use) we will not receive
|
// we sent in the initial NICK command is in use) we will not receive
|
||||||
// a NICK message to confirm our change of nick, so ReNick here...
|
// a NICK message to confirm our change of nick, so ReNick here...
|
||||||
|
@ -89,7 +92,7 @@ func (conn *Conn) h_433(line *Line) {
|
||||||
func (conn *Conn) h_CTCP(line *Line) {
|
func (conn *Conn) h_CTCP(line *Line) {
|
||||||
if line.Args[0] == VERSION {
|
if line.Args[0] == VERSION {
|
||||||
conn.CtcpReply(line.Nick, VERSION, conn.cfg.Version)
|
conn.CtcpReply(line.Nick, VERSION, conn.cfg.Version)
|
||||||
} else if line.Args[0] == PING {
|
} else if line.Args[0] == PING && line.argslen(2) {
|
||||||
conn.CtcpReply(line.Nick, PING, line.Args[2])
|
conn.CtcpReply(line.Nick, PING, line.Args[2])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,8 @@ package client
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
"runtime"
|
||||||
|
"github.com/fluffle/goirc/logging"
|
||||||
)
|
)
|
||||||
|
|
||||||
// We parse an incoming line into this struct. Line.Cmd is used as the trigger
|
// We parse an incoming line into this struct. Line.Cmd is used as the trigger
|
||||||
|
@ -156,3 +158,14 @@ func ParseLine(s string) *Line {
|
||||||
}
|
}
|
||||||
return line
|
return line
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (line *Line) argslen(minlen int) bool {
|
||||||
|
pc, _, _, _ := runtime.Caller(1)
|
||||||
|
fn := runtime.FuncForPC(pc)
|
||||||
|
if len(line.Args) <= minlen {
|
||||||
|
logging.Warn("%s: too few arguments: %s", fn.Name(), strings.Join(line.Args, " "))
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
|
@ -83,6 +83,9 @@ func (conn *Conn) h_PART(line *Line) {
|
||||||
|
|
||||||
// Handle KICKs from channels to maintain state
|
// Handle KICKs from channels to maintain state
|
||||||
func (conn *Conn) h_KICK(line *Line) {
|
func (conn *Conn) h_KICK(line *Line) {
|
||||||
|
if !line.argslen(1) {
|
||||||
|
return
|
||||||
|
}
|
||||||
// XXX: this won't handle autorejoining channels on KICK
|
// XXX: this won't handle autorejoining channels on KICK
|
||||||
// it's trivial to do this in a seperate handler...
|
// it's trivial to do this in a seperate handler...
|
||||||
conn.st.Dissociate(line.Args[0], line.Args[1])
|
conn.st.Dissociate(line.Args[0], line.Args[1])
|
||||||
|
@ -95,6 +98,9 @@ func (conn *Conn) h_QUIT(line *Line) {
|
||||||
|
|
||||||
// Handle MODE changes for channels we know about (and our nick personally)
|
// Handle MODE changes for channels we know about (and our nick personally)
|
||||||
func (conn *Conn) h_MODE(line *Line) {
|
func (conn *Conn) h_MODE(line *Line) {
|
||||||
|
if !line.argslen(1) {
|
||||||
|
return
|
||||||
|
}
|
||||||
if ch := conn.st.GetChannel(line.Args[0]); ch != nil {
|
if ch := conn.st.GetChannel(line.Args[0]); ch != nil {
|
||||||
// channel modes first
|
// channel modes first
|
||||||
conn.st.ChannelModes(line.Args[0], line.Args[1], line.Args[2:]...)
|
conn.st.ChannelModes(line.Args[0], line.Args[1], line.Args[2:]...)
|
||||||
|
@ -114,6 +120,9 @@ func (conn *Conn) h_MODE(line *Line) {
|
||||||
|
|
||||||
// Handle TOPIC changes for channels
|
// Handle TOPIC changes for channels
|
||||||
func (conn *Conn) h_TOPIC(line *Line) {
|
func (conn *Conn) h_TOPIC(line *Line) {
|
||||||
|
if !line.argslen(1) {
|
||||||
|
return
|
||||||
|
}
|
||||||
if ch := conn.st.GetChannel(line.Args[0]); ch != nil {
|
if ch := conn.st.GetChannel(line.Args[0]); ch != nil {
|
||||||
conn.st.Topic(line.Args[0], line.Args[1])
|
conn.st.Topic(line.Args[0], line.Args[1])
|
||||||
} else {
|
} else {
|
||||||
|
@ -124,7 +133,10 @@ func (conn *Conn) h_TOPIC(line *Line) {
|
||||||
|
|
||||||
// Handle 311 whois reply
|
// Handle 311 whois reply
|
||||||
func (conn *Conn) h_311(line *Line) {
|
func (conn *Conn) h_311(line *Line) {
|
||||||
if nk := conn.st.GetNick(line.Args[1]); nk != nil && !conn.Me().Equals(nk) {
|
if !line.argslen(5) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if nk := conn.st.GetNick(line.Args[1]); (nk != nil) && !conn.Me().Equals(nk) {
|
||||||
conn.st.NickInfo(line.Args[1], line.Args[2], line.Args[3], line.Args[5])
|
conn.st.NickInfo(line.Args[1], line.Args[2], line.Args[3], line.Args[5])
|
||||||
} else {
|
} else {
|
||||||
logging.Warn("irc.311(): received WHOIS info for unknown nick %s",
|
logging.Warn("irc.311(): received WHOIS info for unknown nick %s",
|
||||||
|
@ -134,6 +146,9 @@ func (conn *Conn) h_311(line *Line) {
|
||||||
|
|
||||||
// Handle 324 mode reply
|
// Handle 324 mode reply
|
||||||
func (conn *Conn) h_324(line *Line) {
|
func (conn *Conn) h_324(line *Line) {
|
||||||
|
if !line.argslen(2) {
|
||||||
|
return
|
||||||
|
}
|
||||||
if ch := conn.st.GetChannel(line.Args[1]); ch != nil {
|
if ch := conn.st.GetChannel(line.Args[1]); ch != nil {
|
||||||
conn.st.ChannelModes(line.Args[1], line.Args[2], line.Args[3:]...)
|
conn.st.ChannelModes(line.Args[1], line.Args[2], line.Args[3:]...)
|
||||||
} else {
|
} else {
|
||||||
|
@ -144,6 +159,9 @@ func (conn *Conn) h_324(line *Line) {
|
||||||
|
|
||||||
// Handle 332 topic reply on join to channel
|
// Handle 332 topic reply on join to channel
|
||||||
func (conn *Conn) h_332(line *Line) {
|
func (conn *Conn) h_332(line *Line) {
|
||||||
|
if !line.argslen(2) {
|
||||||
|
return
|
||||||
|
}
|
||||||
if ch := conn.st.GetChannel(line.Args[1]); ch != nil {
|
if ch := conn.st.GetChannel(line.Args[1]); ch != nil {
|
||||||
conn.st.Topic(line.Args[1], line.Args[2])
|
conn.st.Topic(line.Args[1], line.Args[2])
|
||||||
} else {
|
} else {
|
||||||
|
@ -154,6 +172,9 @@ func (conn *Conn) h_332(line *Line) {
|
||||||
|
|
||||||
// Handle 352 who reply
|
// Handle 352 who reply
|
||||||
func (conn *Conn) h_352(line *Line) {
|
func (conn *Conn) h_352(line *Line) {
|
||||||
|
if !line.argslen(5) {
|
||||||
|
return
|
||||||
|
}
|
||||||
nk := conn.st.GetNick(line.Args[5])
|
nk := conn.st.GetNick(line.Args[5])
|
||||||
if nk == nil {
|
if nk == nil {
|
||||||
logging.Warn("irc.352(): received WHO reply for unknown nick %s",
|
logging.Warn("irc.352(): received WHO reply for unknown nick %s",
|
||||||
|
@ -168,6 +189,9 @@ func (conn *Conn) h_352(line *Line) {
|
||||||
// last arg contains "<hop count> <real name>"
|
// last arg contains "<hop count> <real name>"
|
||||||
a := strings.SplitN(line.Args[len(line.Args)-1], " ", 2)
|
a := strings.SplitN(line.Args[len(line.Args)-1], " ", 2)
|
||||||
conn.st.NickInfo(nk.Nick, line.Args[2], line.Args[3], a[1])
|
conn.st.NickInfo(nk.Nick, line.Args[2], line.Args[3], a[1])
|
||||||
|
if !line.argslen(6) {
|
||||||
|
return
|
||||||
|
}
|
||||||
if idx := strings.Index(line.Args[6], "*"); idx != -1 {
|
if idx := strings.Index(line.Args[6], "*"); idx != -1 {
|
||||||
conn.st.NickModes(nk.Nick, "+o")
|
conn.st.NickModes(nk.Nick, "+o")
|
||||||
}
|
}
|
||||||
|
@ -181,6 +205,9 @@ func (conn *Conn) h_352(line *Line) {
|
||||||
|
|
||||||
// Handle 353 names reply
|
// Handle 353 names reply
|
||||||
func (conn *Conn) h_353(line *Line) {
|
func (conn *Conn) h_353(line *Line) {
|
||||||
|
if !line.argslen(2) {
|
||||||
|
return
|
||||||
|
}
|
||||||
if ch := conn.st.GetChannel(line.Args[2]); ch != nil {
|
if ch := conn.st.GetChannel(line.Args[2]); ch != nil {
|
||||||
nicks := strings.Split(line.Args[len(line.Args)-1], " ")
|
nicks := strings.Split(line.Args[len(line.Args)-1], " ")
|
||||||
for _, nick := range nicks {
|
for _, nick := range nicks {
|
||||||
|
@ -223,6 +250,9 @@ func (conn *Conn) h_353(line *Line) {
|
||||||
|
|
||||||
// Handle 671 whois reply (nick connected via SSL)
|
// Handle 671 whois reply (nick connected via SSL)
|
||||||
func (conn *Conn) h_671(line *Line) {
|
func (conn *Conn) h_671(line *Line) {
|
||||||
|
if !line.argslen(1) {
|
||||||
|
return
|
||||||
|
}
|
||||||
if nk := conn.st.GetNick(line.Args[1]); nk != nil {
|
if nk := conn.st.GetNick(line.Args[1]); nk != nil {
|
||||||
conn.st.NickModes(nk.Nick, "+z")
|
conn.st.NickModes(nk.Nick, "+z")
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue