From b49099e0755f8841084edf2817fcac2cd1a512ec Mon Sep 17 00:00:00 2001 From: Andy Walker Date: Mon, 20 Jul 2015 16:13:15 -0400 Subject: [PATCH 1/5] use rand.Seed() in init() to properly randomize --- irc_callback.go | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/irc_callback.go b/irc_callback.go index a7576c9..d7abf74 100644 --- a/irc_callback.go +++ b/irc_callback.go @@ -161,14 +161,14 @@ func (irc *Connection) setupCallbacks() { irc.AddCallback("CTCP_PING", func(e *Event) { irc.SendRawf("NOTICE %s :\x01%s\x01", e.Nick, e.Message()) }) // 437: ERR_UNAVAILRESOURCE " :Nick/channel is temporarily unavailable" - // Add a _ to current nick. If irc.nickcurrent is empty this cannot - // work. It has to be set somewhere first in case the nick is already - // taken or unavailable from the beginning. - irc.AddCallback("437", func(e *Event) { - // If irc.nickcurrent hasn't been set yet, set to irc.nick - if irc.nickcurrent == "" { - irc.nickcurrent = irc.nick - } + // Add a _ to current nick. If irc.nickcurrent is empty this cannot + // work. It has to be set somewhere first in case the nick is already + // taken or unavailable from the beginning. + irc.AddCallback("437", func(e *Event) { + // If irc.nickcurrent hasn't been set yet, set to irc.nick + if irc.nickcurrent == "" { + irc.nickcurrent = irc.nick + } if len(irc.nickcurrent) > 8 { irc.nickcurrent = "_" + irc.nickcurrent @@ -181,10 +181,10 @@ func (irc *Connection) setupCallbacks() { // 433: ERR_NICKNAMEINUSE " :Nickname is already in use" // Add a _ to current nick. irc.AddCallback("433", func(e *Event) { - // If irc.nickcurrent hasn't been set yet, set to irc.nick - if irc.nickcurrent == "" { - irc.nickcurrent = irc.nick - } + // If irc.nickcurrent hasn't been set yet, set to irc.nick + if irc.nickcurrent == "" { + irc.nickcurrent = irc.nick + } if len(irc.nickcurrent) > 8 { irc.nickcurrent = "_" + irc.nickcurrent @@ -216,3 +216,7 @@ func (irc *Connection) setupCallbacks() { irc.nickcurrent = e.Arguments[0] }) } + +func init() { + rand.Seed(time.Now().UnixNano()) +} From ad73608a8738d746c1dd198b49519221c6decbb9 Mon Sep 17 00:00:00 2001 From: Andy Walker Date: Tue, 21 Jul 2015 18:41:16 -0400 Subject: [PATCH 2/5] add Kick and MultiKick commands --- irc.go | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/irc.go b/irc.go index 56d7c07..3d3be3e 100644 --- a/irc.go +++ b/irc.go @@ -20,6 +20,7 @@ package irc import ( "bufio" + "bytes" "crypto/tls" "errors" "fmt" @@ -245,6 +246,29 @@ func (irc *Connection) Privmsgf(target, format string, a ...interface{}) { irc.Privmsg(target, fmt.Sprintf(format, a...)) } +// Kick from with . For no message, pass empty string ("") +func (irc *Connection) Kick(user, channel, msg string) { + var cmd bytes.Buffer + cmd.WriteString(fmt.Sprintf("KICK %s %s", channel, user)) + if msg != "" { + cmd.WriteString(fmt.Sprintf(" :%s", msg)) + } + cmd.WriteString("\r\n") + irc.pwrite <- cmd.String() +} + +// Kick all from with . For no message, pass +// empty string ("") +func (irc *Connection) MultiKick(users []string, channel string, msg string) { + var cmd bytes.Buffer + cmd.WriteString(fmt.Sprintf("KICK %s %s", channel, strings.Join(users, " "))) + if msg != "" { + cmd.WriteString(fmt.Sprintf(" :%s", msg)) + } + cmd.WriteString("\r\n") + irc.pwrite <- cmd.String() +} + // Send raw string. func (irc *Connection) SendRaw(message string) { irc.pwrite <- message + "\r\n" From 6112236593e0685877ddd60c8ab6fdd4428733cd Mon Sep 17 00:00:00 2001 From: Andy Walker Date: Thu, 30 Jul 2015 12:57:48 -0400 Subject: [PATCH 3/5] fix multi-kick Spec defines multiple users as joined by spaces not commas --- irc.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/irc.go b/irc.go index 3d3be3e..16e3b58 100644 --- a/irc.go +++ b/irc.go @@ -261,7 +261,7 @@ func (irc *Connection) Kick(user, channel, msg string) { // empty string ("") func (irc *Connection) MultiKick(users []string, channel string, msg string) { var cmd bytes.Buffer - cmd.WriteString(fmt.Sprintf("KICK %s %s", channel, strings.Join(users, " "))) + cmd.WriteString(fmt.Sprintf("KICK %s %s", channel, strings.Join(users, ","))) if msg != "" { cmd.WriteString(fmt.Sprintf(" :%s", msg)) } From 03b22b08f42f39e3513c33460c16871005a8f395 Mon Sep 17 00:00:00 2001 From: Andy Walker Date: Thu, 30 Jul 2015 12:58:23 -0400 Subject: [PATCH 4/5] Report on unterminated CTCP messages A bug was discovered where, under certain circumstances that are still being researched, the library would panic on a message that started with \0x01, but did not end with it. This would cause the re-slice to panic, because the library assumes a terminating index >0, effectively introducing the possibility of msg = msg[1:0]. Since this violates the CTCP spec, it is an error, and should be logged, along with the complete, escaped message. --- irc_callback.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/irc_callback.go b/irc_callback.go index d7abf74..7da4226 100644 --- a/irc_callback.go +++ b/irc_callback.go @@ -80,8 +80,10 @@ func (irc *Connection) RunCallbacks(event *Event) { if event.Code == "PRIVMSG" && len(msg) > 2 && msg[0] == '\x01' { event.Code = "CTCP" //Unknown CTCP - if i := strings.LastIndex(msg, "\x01"); i > -1 { + if i := strings.LastIndex(msg, "\x01"); i > 0 { msg = msg[1:i] + } else { + irc.Log.Printf("Invalid CTCP Message: %s\n", strconv.Quote(msg)) } if msg == "VERSION" { From b0ed3d4bd5c60abbd8c1f141df10f44fd8dd1110 Mon Sep 17 00:00:00 2001 From: Andy Walker Date: Thu, 30 Jul 2015 13:03:55 -0400 Subject: [PATCH 5/5] should return in case of CTCP error --- irc_callback.go | 1 + 1 file changed, 1 insertion(+) diff --git a/irc_callback.go b/irc_callback.go index 7da4226..4b71b3b 100644 --- a/irc_callback.go +++ b/irc_callback.go @@ -84,6 +84,7 @@ func (irc *Connection) RunCallbacks(event *Event) { msg = msg[1:i] } else { irc.Log.Printf("Invalid CTCP Message: %s\n", strconv.Quote(msg)) + return } if msg == "VERSION" {