From 819351eab3fc4c2f1d7adc8c3e753312ea83dcc9 Mon Sep 17 00:00:00 2001 From: Wessie Date: Wed, 24 Jan 2024 12:20:50 +0100 Subject: [PATCH] Fix #63 Logic race condition, if the decode goroutine can run before the caller can the channel returned might not have a receiver yet and then the select/default construct will drop the event and close the channel. The caller then ends up with a zero-value decodedEvent where decodedEvent.err and decodedEvent.event are both nil which passes the err check at line 434 and might enter line 440 where decodedEvent.event is then used as-is with no additional check for it being nil. --- conn.go | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/conn.go b/conn.go index c32eca6..2ae1831 100644 --- a/conn.go +++ b/conn.go @@ -150,35 +150,24 @@ type decodedEvent struct { } func (c *ircConn) decode() <-chan decodedEvent { - ch := make(chan decodedEvent) + ch := make(chan decodedEvent, 1) go func() { defer close(ch) line, err := c.io.ReadString(delim) if err != nil { - select { - case ch <- decodedEvent{err: err}: - default: - } - + ch <- decodedEvent{err: err} return } event := ParseEvent(line) if event == nil { - select { - case ch <- decodedEvent{err: ErrParseEvent{Line: line}}: - default: - } - + ch <- decodedEvent{err: ErrParseEvent{Line: line}} return } - select { - case ch <- decodedEvent{event: event}: - default: - } + ch <- decodedEvent{event: event} }() return ch