mirror of
				https://github.com/fluffle/goirc
				synced 2025-11-04 03:58:03 +00:00 
			
		
		
		
	Merge pull request #72 from soul9/master
handlers: check array bounds before indexing
This commit is contained in:
		
						commit
						b38d16353c
					
				
					 3 changed files with 48 additions and 2 deletions
				
			
		| 
						 | 
					@ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue